bun-query-builder 0.1.6 → 0.1.8

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.
Files changed (2) hide show
  1. package/dist/index.js +3493 -286
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -28,19 +28,26 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
28
28
  var __promiseAll = (args) => Promise.all(args);
29
29
  var __require = import.meta.require;
30
30
 
31
- // ../../node_modules/.bun/bunfig@0.15.0/node_modules/bunfig/dist/index.js
31
+ // ../../node_modules/.bun/bunfig@0.15.6/node_modules/bunfig/dist/index.js
32
+ import { existsSync, statSync } from "fs";
33
+ import { existsSync as existsSync8, mkdirSync as mkdirSync3, readdirSync as readdirSync3, writeFileSync as writeFileSync5 } from "fs";
34
+ import { homedir as homedir2 } from "os";
35
+ import { dirname as dirname3, resolve as resolve7 } from "path";
36
+ import process12 from "process";
37
+ import { join as join3, relative as relative2, resolve as resolve4 } from "path";
38
+ import process7 from "process";
32
39
  import { existsSync as existsSync3, mkdirSync as mkdirSync2, readdirSync as readdirSync2, writeFileSync as writeFileSync3 } from "fs";
33
40
  import { homedir } from "os";
34
41
  import { dirname as dirname2, resolve as resolve3 } from "path";
35
42
  import process6 from "process";
36
43
  import { join, relative, resolve as resolve2 } from "path";
37
44
  import process2 from "process";
38
- import { existsSync, mkdirSync, readdirSync, writeFileSync } from "fs";
45
+ import { existsSync as existsSync2, mkdirSync, readdirSync, writeFileSync } from "fs";
39
46
  import { dirname, resolve } from "path";
40
47
  import process from "process";
41
48
  import { Buffer } from "buffer";
42
49
  import { createCipheriv, createDecipheriv, randomBytes } from "crypto";
43
- import { closeSync, createReadStream, createWriteStream, existsSync as existsSync2, fsyncSync, openSync, writeFileSync as writeFileSync2 } from "fs";
50
+ import { closeSync, createReadStream, createWriteStream, existsSync as existsSync22, fsyncSync, openSync, writeFileSync as writeFileSync2 } from "fs";
44
51
  import { access, constants, mkdir, readdir, rename, stat, unlink, writeFile } from "fs/promises";
45
52
  import { join as join2 } from "path";
46
53
  import process5 from "process";
@@ -48,6 +55,259 @@ import { pipeline } from "stream/promises";
48
55
  import { createGzip } from "zlib";
49
56
  import process4 from "process";
50
57
  import process3 from "process";
58
+ import { Buffer as Buffer2 } from "buffer";
59
+ import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes2 } from "crypto";
60
+ import { closeSync as closeSync2, createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync4, fsyncSync as fsyncSync2, openSync as openSync2, writeFileSync as writeFileSync4 } from "fs";
61
+ 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";
62
+ import { isAbsolute, join as join5, resolve as resolve6 } from "path";
63
+ import process11 from "process";
64
+ import { pipeline as pipeline2 } from "stream/promises";
65
+ import { createGzip as createGzip2 } from "zlib";
66
+ import process10 from "process";
67
+ import process9 from "process";
68
+ import process8 from "process";
69
+ import { existsSync as existsSync5 } from "fs";
70
+ import { resolve as resolve5 } from "path";
71
+ import { existsSync as existsSync7 } from "fs";
72
+
73
+ class ConfigCache {
74
+ cache = new Map;
75
+ totalHits = 0;
76
+ totalMisses = 0;
77
+ options;
78
+ constructor(options = {}) {
79
+ this.options = {
80
+ enabled: true,
81
+ ttl: 5 * 60 * 1000,
82
+ maxSize: 100,
83
+ keyPrefix: "bunfig:",
84
+ ...options
85
+ };
86
+ }
87
+ generateKey(configName, configPath) {
88
+ const pathKey = configPath ? `:${configPath}` : "";
89
+ return `${this.options.keyPrefix}${configName}${pathKey}`;
90
+ }
91
+ isExpired(entry) {
92
+ const now = Date.now();
93
+ const age = now - entry.timestamp.getTime();
94
+ const expired = age > entry.ttl;
95
+ return expired;
96
+ }
97
+ estimateSize(value) {
98
+ try {
99
+ return JSON.stringify(value).length;
100
+ } catch {
101
+ return 1000;
102
+ }
103
+ }
104
+ evictIfNeeded() {
105
+ if (this.cache.size <= this.options.maxSize) {
106
+ return;
107
+ }
108
+ const entries = Array.from(this.cache.entries()).sort(([, a], [, b]) => a.timestamp.getTime() - b.timestamp.getTime());
109
+ const toRemove = entries.length - this.options.maxSize + 1;
110
+ for (let i = 0;i < toRemove; i++) {
111
+ this.cache.delete(entries[i][0]);
112
+ }
113
+ }
114
+ set(configName, value, configPath, customTtl) {
115
+ if (!this.options.enabled) {
116
+ return;
117
+ }
118
+ const key = this.generateKey(configName, configPath);
119
+ const ttl = customTtl ?? this.options.ttl;
120
+ const size = this.estimateSize(value);
121
+ this.cache.set(key, {
122
+ value,
123
+ timestamp: new Date,
124
+ ttl,
125
+ hits: 0,
126
+ size
127
+ });
128
+ this.evictIfNeeded();
129
+ }
130
+ get(configName, configPath) {
131
+ if (!this.options.enabled) {
132
+ this.totalMisses++;
133
+ return;
134
+ }
135
+ const key = this.generateKey(configName, configPath);
136
+ const entry = this.cache.get(key);
137
+ if (!entry) {
138
+ this.totalMisses++;
139
+ return;
140
+ }
141
+ if (this.isExpired(entry)) {
142
+ this.cache.delete(key);
143
+ this.totalMisses++;
144
+ return;
145
+ }
146
+ entry.hits++;
147
+ this.totalHits++;
148
+ return entry.value;
149
+ }
150
+ isFileModified(configPath, cachedTimestamp) {
151
+ try {
152
+ if (!existsSync(configPath)) {
153
+ return true;
154
+ }
155
+ const stats = statSync(configPath);
156
+ return stats.mtime > cachedTimestamp;
157
+ } catch {
158
+ return true;
159
+ }
160
+ }
161
+ getWithFileCheck(configName, configPath) {
162
+ const cached = this.get(configName, configPath);
163
+ if (!cached) {
164
+ return;
165
+ }
166
+ if (this.isFileModified(configPath, cached.fileTimestamp)) {
167
+ this.delete(configName, configPath);
168
+ return;
169
+ }
170
+ return cached.value;
171
+ }
172
+ setWithFileCheck(configName, value, configPath, customTtl) {
173
+ try {
174
+ const stats = existsSync(configPath) ? statSync(configPath) : null;
175
+ const fileTimestamp = stats ? stats.mtime : new Date;
176
+ this.set(configName, { value, fileTimestamp }, configPath, customTtl);
177
+ } catch {
178
+ this.set(configName, value, configPath, customTtl);
179
+ }
180
+ }
181
+ delete(configName, configPath) {
182
+ const key = this.generateKey(configName, configPath);
183
+ return this.cache.delete(key);
184
+ }
185
+ clear() {
186
+ this.cache.clear();
187
+ this.totalHits = 0;
188
+ this.totalMisses = 0;
189
+ }
190
+ cleanup() {
191
+ let cleaned = 0;
192
+ for (const [key, entry] of this.cache.entries()) {
193
+ if (this.isExpired(entry)) {
194
+ this.cache.delete(key);
195
+ cleaned++;
196
+ }
197
+ }
198
+ return cleaned;
199
+ }
200
+ getStats() {
201
+ const entries = Array.from(this.cache.values());
202
+ const totalSize = entries.reduce((sum, entry) => sum + entry.size, 0);
203
+ const timestamps = entries.map((entry) => entry.timestamp).sort();
204
+ return {
205
+ size: totalSize,
206
+ maxSize: this.options.maxSize,
207
+ hitRate: this.totalHits + this.totalMisses > 0 ? this.totalHits / (this.totalHits + this.totalMisses) : 0,
208
+ totalHits: this.totalHits,
209
+ totalMisses: this.totalMisses,
210
+ entries: this.cache.size,
211
+ oldestEntry: timestamps[0],
212
+ newestEntry: timestamps[timestamps.length - 1]
213
+ };
214
+ }
215
+ export() {
216
+ const data = {};
217
+ for (const [key, entry] of this.cache.entries()) {
218
+ data[key] = {
219
+ value: entry.value,
220
+ timestamp: entry.timestamp.toISOString(),
221
+ ttl: entry.ttl,
222
+ hits: entry.hits,
223
+ size: entry.size
224
+ };
225
+ }
226
+ return data;
227
+ }
228
+ import(data) {
229
+ this.cache.clear();
230
+ for (const [key, entryData] of Object.entries(data)) {
231
+ if (typeof entryData === "object" && entryData !== null) {
232
+ const entry = entryData;
233
+ this.cache.set(key, {
234
+ value: entry.value,
235
+ timestamp: new Date(entry.timestamp),
236
+ ttl: entry.ttl,
237
+ hits: entry.hits,
238
+ size: entry.size
239
+ });
240
+ }
241
+ }
242
+ }
243
+ }
244
+
245
+ class PerformanceMonitor {
246
+ metrics = [];
247
+ maxMetrics = 1000;
248
+ async track(operation, fn, context = {}) {
249
+ const start = performance.now();
250
+ const startTime = new Date;
251
+ try {
252
+ const result = await fn();
253
+ const duration = performance.now() - start;
254
+ this.recordMetric({
255
+ operation,
256
+ duration,
257
+ timestamp: startTime,
258
+ ...context
259
+ });
260
+ return result;
261
+ } catch (error) {
262
+ const duration = performance.now() - start;
263
+ this.recordMetric({
264
+ operation: `${operation}:error`,
265
+ duration,
266
+ timestamp: startTime,
267
+ ...context
268
+ });
269
+ throw error;
270
+ }
271
+ }
272
+ recordMetric(metric) {
273
+ this.metrics.push(metric);
274
+ if (this.metrics.length > this.maxMetrics) {
275
+ this.metrics = this.metrics.slice(-this.maxMetrics);
276
+ }
277
+ }
278
+ getStats(operation) {
279
+ const filteredMetrics = operation ? this.metrics.filter((m) => m.operation === operation) : this.metrics;
280
+ if (filteredMetrics.length === 0) {
281
+ return {
282
+ count: 0,
283
+ averageDuration: 0,
284
+ minDuration: 0,
285
+ maxDuration: 0,
286
+ totalDuration: 0,
287
+ recentMetrics: []
288
+ };
289
+ }
290
+ const durations = filteredMetrics.map((m) => m.duration);
291
+ const totalDuration = durations.reduce((sum, d) => sum + d, 0);
292
+ return {
293
+ count: filteredMetrics.length,
294
+ averageDuration: totalDuration / filteredMetrics.length,
295
+ minDuration: Math.min(...durations),
296
+ maxDuration: Math.max(...durations),
297
+ totalDuration,
298
+ recentMetrics: filteredMetrics.slice(-10)
299
+ };
300
+ }
301
+ getAllMetrics() {
302
+ return [...this.metrics];
303
+ }
304
+ clearMetrics() {
305
+ this.metrics = [];
306
+ }
307
+ getSlowOperations(threshold) {
308
+ return this.metrics.filter((m) => m.duration > threshold);
309
+ }
310
+ }
51
311
  function deepMerge(target, source) {
52
312
  if (Array.isArray(source) && Array.isArray(target) && source.length === 2 && target.length === 2 && isObject(source[0]) && "id" in source[0] && source[0].id === 3 && isObject(source[1]) && "id" in source[1] && source[1].id === 4) {
53
313
  return source;
@@ -174,7 +434,7 @@ function isObject(item) {
174
434
  return Boolean(item && typeof item === "object" && !Array.isArray(item));
175
435
  }
176
436
  async function tryLoadConfig(configPath, defaultConfig) {
177
- if (!existsSync(configPath))
437
+ if (!existsSync2(configPath))
178
438
  return null;
179
439
  try {
180
440
  const importedConfig = await import(configPath);
@@ -214,7 +474,7 @@ async function loadConfig({
214
474
  }
215
475
  try {
216
476
  const pkgPath = resolve(baseDir, "package.json");
217
- if (existsSync(pkgPath)) {
477
+ if (existsSync2(pkgPath)) {
218
478
  const pkg = await import(pkgPath);
219
479
  const pkgConfig = pkg[name];
220
480
  if (pkgConfig && typeof pkgConfig === "object" && !Array.isArray(pkgConfig)) {
@@ -443,7 +703,7 @@ class Logger {
443
703
  throw new Error("Operation cancelled: Logger was destroyed");
444
704
  const dataToWrite = this.validateEncryptionConfig() ? (await this.encrypt(data)).encrypted : Buffer.from(data);
445
705
  try {
446
- if (!existsSync2(this.currentLogFile)) {
706
+ if (!existsSync22(this.currentLogFile)) {
447
707
  await writeFile(this.currentLogFile, "", { mode: 420 });
448
708
  }
449
709
  fd = openSync(this.currentLogFile, "a", 420);
@@ -779,7 +1039,7 @@ class Logger {
779
1039
  }
780
1040
  return Promise.resolve();
781
1041
  }));
782
- if (existsSync2(this.currentLogFile)) {
1042
+ if (existsSync22(this.currentLogFile)) {
783
1043
  try {
784
1044
  const fd = openSync(this.currentLogFile, "r+");
785
1045
  fsyncSync(fd);
@@ -1099,7 +1359,7 @@ class Logger {
1099
1359
  createReadStream() {
1100
1360
  if (isBrowserProcess())
1101
1361
  throw new Error("createReadStream is not supported in browser environments");
1102
- if (!existsSync2(this.currentLogFile))
1362
+ if (!existsSync22(this.currentLogFile))
1103
1363
  throw new Error(`Log file does not exist: ${this.currentLogFile}`);
1104
1364
  return createReadStream(this.currentLogFile, { encoding: "utf8" });
1105
1365
  }
@@ -1709,84 +1969,2772 @@ async function loadConfig3({
1709
1969
  return config3;
1710
1970
  }
1711
1971
  }
1712
- }
1972
+ }
1973
+ }
1974
+ if (name) {
1975
+ const homeConfigDir = resolve3(homedir(), ".config");
1976
+ const homeConfigDotfilePatterns = [`.${name}.config`];
1977
+ if (alias)
1978
+ homeConfigDotfilePatterns.push(`.${alias}.config`);
1979
+ if (verbose)
1980
+ log.info(`Checking user config directory for dotfile configs: ${homeConfigDir}`);
1981
+ for (const configPath of homeConfigDotfilePatterns) {
1982
+ for (const ext of extensions) {
1983
+ const fullPath = resolve3(homeConfigDir, `${configPath}${ext}`);
1984
+ const config3 = await tryLoadConfig2(fullPath, configWithEnvVars, arrayStrategy);
1985
+ if (config3 !== null) {
1986
+ if (verbose)
1987
+ log.success(`Configuration loaded from user config directory dotfile: ${fullPath}`);
1988
+ return config3;
1989
+ }
1990
+ }
1991
+ }
1992
+ }
1993
+ if (name) {
1994
+ const homeDir = homedir();
1995
+ const homeRootPatterns = [`.${name}.config`, `.${name}`];
1996
+ if (alias) {
1997
+ homeRootPatterns.push(`.${alias}.config`);
1998
+ homeRootPatterns.push(`.${alias}`);
1999
+ }
2000
+ if (verbose)
2001
+ log.info(`Checking user home directory for dotfile configs: ${homeDir}`);
2002
+ for (const configPath of homeRootPatterns) {
2003
+ for (const ext of extensions) {
2004
+ const fullPath = resolve3(homeDir, `${configPath}${ext}`);
2005
+ const config3 = await tryLoadConfig2(fullPath, configWithEnvVars, arrayStrategy);
2006
+ if (config3 !== null) {
2007
+ if (verbose)
2008
+ log.success(`Configuration loaded from user home directory: ${fullPath}`);
2009
+ return config3;
2010
+ }
2011
+ }
2012
+ }
2013
+ }
2014
+ try {
2015
+ const pkgPath = resolve3(baseDir, "package.json");
2016
+ if (existsSync3(pkgPath)) {
2017
+ const pkg = await import(pkgPath);
2018
+ let pkgConfig = pkg[name];
2019
+ if (!pkgConfig && alias) {
2020
+ pkgConfig = pkg[alias];
2021
+ if (pkgConfig && verbose) {
2022
+ log.success(`Using alias "${alias}" configuration from package.json`);
2023
+ }
2024
+ }
2025
+ if (pkgConfig && typeof pkgConfig === "object" && !Array.isArray(pkgConfig)) {
2026
+ try {
2027
+ if (verbose) {
2028
+ log.success(`Configuration loaded from package.json: ${pkgConfig === pkg[name] ? name : alias}`);
2029
+ }
2030
+ return deepMergeWithArrayStrategy(configWithEnvVars, pkgConfig, arrayStrategy);
2031
+ } catch (error) {
2032
+ if (verbose) {
2033
+ log.warn(`Failed to merge package.json config:`, error);
2034
+ }
2035
+ }
2036
+ }
2037
+ }
2038
+ } catch (error) {
2039
+ if (verbose) {
2040
+ log.warn(`Failed to load package.json:`, error);
2041
+ }
2042
+ }
2043
+ if (verbose) {
2044
+ log.info(`No configuration found for "${name}"${alias ? ` or alias "${alias}"` : ""}, using default configuration with environment variables`);
2045
+ }
2046
+ return configWithEnvVars;
2047
+ }
2048
+ function getProjectRoot2(filePath, options = {}) {
2049
+ let path = process7.cwd();
2050
+ while (path.includes("storage"))
2051
+ path = resolve4(path, "..");
2052
+ const finalPath = resolve4(path, filePath || "");
2053
+ if (options?.relative)
2054
+ return relative2(process7.cwd(), finalPath);
2055
+ return finalPath;
2056
+ }
2057
+ async function loadConfig4() {
2058
+ try {
2059
+ const loadedConfig = await loadConfig3({
2060
+ name: "clarity",
2061
+ alias: "logging",
2062
+ defaultConfig: defaultConfig2,
2063
+ cwd: process7.cwd()
2064
+ });
2065
+ return { ...defaultConfig2, ...loadedConfig || {} };
2066
+ } catch {
2067
+ return defaultConfig2;
2068
+ }
2069
+ }
2070
+ function isBrowserProcess2() {
2071
+ if (process9.env.NODE_ENV === "test" || process9.env.BUN_ENV === "test") {
2072
+ return false;
2073
+ }
2074
+ return typeof window !== "undefined";
2075
+ }
2076
+ async function isServerProcess2() {
2077
+ if (process9.env.NODE_ENV === "test" || process9.env.BUN_ENV === "test") {
2078
+ return true;
2079
+ }
2080
+ if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
2081
+ return true;
2082
+ }
2083
+ if (typeof process9 !== "undefined") {
2084
+ const type = process9.type;
2085
+ if (type === "renderer" || type === "worker") {
2086
+ return false;
2087
+ }
2088
+ return !!(process9.versions && (process9.versions.node || process9.versions.bun));
2089
+ }
2090
+ return false;
2091
+ }
2092
+
2093
+ class JsonFormatter2 {
2094
+ async format(entry) {
2095
+ const isServer = await isServerProcess2();
2096
+ const metadata = await this.getMetadata(isServer);
2097
+ return JSON.stringify({
2098
+ timestamp: entry.timestamp.toISOString(),
2099
+ level: entry.level,
2100
+ name: entry.name,
2101
+ message: entry.message,
2102
+ metadata
2103
+ });
2104
+ }
2105
+ async getMetadata(isServer) {
2106
+ if (isServer) {
2107
+ const { hostname } = await import("os");
2108
+ return {
2109
+ pid: process10.pid,
2110
+ hostname: hostname(),
2111
+ environment: process10.env.NODE_ENV || "development",
2112
+ platform: process10.platform,
2113
+ version: process10.version
2114
+ };
2115
+ }
2116
+ return {
2117
+ userAgent: navigator.userAgent,
2118
+ hostname: window.location.hostname || "browser",
2119
+ environment: process10.env.NODE_ENV || process10.env.BUN_ENV || "development",
2120
+ viewport: {
2121
+ width: window.innerWidth,
2122
+ height: window.innerHeight
2123
+ },
2124
+ language: navigator.language
2125
+ };
2126
+ }
2127
+ }
2128
+
2129
+ class Logger2 {
2130
+ name;
2131
+ fileLocks = new Map;
2132
+ currentKeyId = null;
2133
+ keys = new Map;
2134
+ fingersCrossedConfig;
2135
+ fingersCrossedActive = false;
2136
+ currentLogFile;
2137
+ rotationTimeout;
2138
+ keyRotationTimeout;
2139
+ encryptionKeys;
2140
+ logBuffer = [];
2141
+ isActivated = false;
2142
+ pendingOperations = [];
2143
+ enabled;
2144
+ fancy;
2145
+ tagFormat;
2146
+ timestampPosition;
2147
+ environment;
2148
+ config;
2149
+ options;
2150
+ formatter;
2151
+ timers = new Set;
2152
+ subLoggers = new Set;
2153
+ fingersCrossedBuffer = [];
2154
+ ANSI_PATTERN = /\u001B\[.*?m/g;
2155
+ activeProgressBar = null;
2156
+ constructor(name, options = {}) {
2157
+ this.name = name;
2158
+ this.config = { ...config2 };
2159
+ this.options = this.normalizeOptions(options);
2160
+ this.formatter = this.options.formatter || new JsonFormatter2;
2161
+ this.enabled = options.enabled ?? true;
2162
+ this.fancy = options.fancy ?? true;
2163
+ this.tagFormat = options.tagFormat ?? { prefix: "[", suffix: "]" };
2164
+ this.timestampPosition = options.timestampPosition ?? "right";
2165
+ this.environment = options.environment ?? process11.env.APP_ENV ?? "local";
2166
+ this.fingersCrossedConfig = this.initializeFingersCrossedConfig(options);
2167
+ const configOptions = { ...options };
2168
+ const hasTimestamp = options.timestamp !== undefined;
2169
+ if (hasTimestamp) {
2170
+ delete configOptions.timestamp;
2171
+ }
2172
+ this.config = {
2173
+ ...this.config,
2174
+ ...configOptions,
2175
+ timestamp: hasTimestamp || this.config.timestamp
2176
+ };
2177
+ this.currentLogFile = this.generateLogFilename();
2178
+ this.encryptionKeys = new Map;
2179
+ if (this.validateEncryptionConfig()) {
2180
+ this.setupRotation();
2181
+ const initialKeyId = this.generateKeyId();
2182
+ const initialKey = this.generateKey();
2183
+ this.currentKeyId = initialKeyId;
2184
+ this.keys.set(initialKeyId, initialKey);
2185
+ this.encryptionKeys.set(initialKeyId, {
2186
+ key: initialKey,
2187
+ createdAt: new Date
2188
+ });
2189
+ this.setupKeyRotation();
2190
+ }
2191
+ }
2192
+ shouldActivateFingersCrossed(level) {
2193
+ if (!this.fingersCrossedConfig)
2194
+ return false;
2195
+ const levels = {
2196
+ debug: 0,
2197
+ info: 1,
2198
+ success: 2,
2199
+ warning: 3,
2200
+ error: 4
2201
+ };
2202
+ const activation = this.fingersCrossedConfig.activationLevel ?? "error";
2203
+ return levels[level] >= levels[activation];
2204
+ }
2205
+ initializeFingersCrossedConfig(options) {
2206
+ if (!options.fingersCrossedEnabled && options.fingersCrossed) {
2207
+ return {
2208
+ ...defaultFingersCrossedConfig2,
2209
+ ...options.fingersCrossed
2210
+ };
2211
+ }
2212
+ if (!options.fingersCrossedEnabled) {
2213
+ return null;
2214
+ }
2215
+ if (!options.fingersCrossed) {
2216
+ return { ...defaultFingersCrossedConfig2 };
2217
+ }
2218
+ return {
2219
+ ...defaultFingersCrossedConfig2,
2220
+ ...options.fingersCrossed
2221
+ };
2222
+ }
2223
+ normalizeOptions(options) {
2224
+ const defaultOptions = {
2225
+ format: "json",
2226
+ level: "info",
2227
+ logDirectory: config2.logDirectory,
2228
+ rotation: undefined,
2229
+ timestamp: undefined,
2230
+ fingersCrossed: {},
2231
+ enabled: true,
2232
+ showTags: false,
2233
+ showIcons: true,
2234
+ formatter: undefined
2235
+ };
2236
+ const mergedOptions = {
2237
+ ...defaultOptions,
2238
+ ...Object.fromEntries(Object.entries(options).filter(([, value]) => value !== undefined))
2239
+ };
2240
+ if (!mergedOptions.level || !["debug", "info", "success", "warning", "error"].includes(mergedOptions.level)) {
2241
+ mergedOptions.level = defaultOptions.level;
2242
+ }
2243
+ return mergedOptions;
2244
+ }
2245
+ shouldWriteToFile() {
2246
+ return !isBrowserProcess2() && this.config.writeToFile === true;
2247
+ }
2248
+ async writeToFile(data) {
2249
+ const cancelled = false;
2250
+ const operationPromise = (async () => {
2251
+ let fd;
2252
+ let retries = 0;
2253
+ const maxRetries = 3;
2254
+ const backoffDelay = 1000;
2255
+ while (retries < maxRetries) {
2256
+ try {
2257
+ try {
2258
+ try {
2259
+ await access2(this.config.logDirectory, constants2.F_OK | constants2.W_OK);
2260
+ } catch (err) {
2261
+ if (err instanceof Error && "code" in err) {
2262
+ if (err.code === "ENOENT") {
2263
+ await mkdir2(this.config.logDirectory, { recursive: true, mode: 493 });
2264
+ } else if (err.code === "EACCES") {
2265
+ throw new Error(`No write permission for log directory: ${this.config.logDirectory}`);
2266
+ } else {
2267
+ throw err;
2268
+ }
2269
+ } else {
2270
+ throw err;
2271
+ }
2272
+ }
2273
+ } catch (err) {
2274
+ console.error("Debug: [writeToFile] Failed to create log directory:", err);
2275
+ throw err;
2276
+ }
2277
+ if (cancelled)
2278
+ throw new Error("Operation cancelled: Logger was destroyed");
2279
+ const dataToWrite = this.validateEncryptionConfig() ? (await this.encrypt(data)).encrypted : Buffer2.from(data);
2280
+ try {
2281
+ if (!existsSync4(this.currentLogFile)) {
2282
+ await writeFile2(this.currentLogFile, "", { mode: 420 });
2283
+ }
2284
+ fd = openSync2(this.currentLogFile, "a", 420);
2285
+ writeFileSync4(fd, dataToWrite, { flag: "a" });
2286
+ fsyncSync2(fd);
2287
+ if (fd !== undefined) {
2288
+ closeSync2(fd);
2289
+ fd = undefined;
2290
+ }
2291
+ const stats = await stat2(this.currentLogFile);
2292
+ if (stats.size === 0) {
2293
+ await writeFile2(this.currentLogFile, dataToWrite, { flag: "w", mode: 420 });
2294
+ const retryStats = await stat2(this.currentLogFile);
2295
+ if (retryStats.size === 0) {
2296
+ throw new Error("File exists but is empty after retry write");
2297
+ }
2298
+ }
2299
+ return;
2300
+ } catch (err) {
2301
+ const error = err;
2302
+ if (error.code && ["ENETDOWN", "ENETUNREACH", "ENOTFOUND", "ETIMEDOUT"].includes(error.code)) {
2303
+ if (retries < maxRetries - 1) {
2304
+ const errorMessage = typeof error.message === "string" ? error.message : "Unknown error";
2305
+ console.error(`Network error during write attempt ${retries + 1}/${maxRetries}:`, errorMessage);
2306
+ const delay = backoffDelay * 2 ** retries;
2307
+ await new Promise((resolve52) => setTimeout(resolve52, delay));
2308
+ retries++;
2309
+ continue;
2310
+ }
2311
+ }
2312
+ if (error?.code && ["ENOSPC", "EDQUOT"].includes(error.code)) {
2313
+ throw new Error(`Disk quota exceeded or no space left on device: ${error.message}`);
2314
+ }
2315
+ console.error("Debug: [writeToFile] Error writing to file:", error);
2316
+ throw error;
2317
+ } finally {
2318
+ if (fd !== undefined) {
2319
+ try {
2320
+ closeSync2(fd);
2321
+ } catch (err) {
2322
+ console.error("Debug: [writeToFile] Error closing file descriptor:", err);
2323
+ }
2324
+ }
2325
+ }
2326
+ } catch (err) {
2327
+ if (retries === maxRetries - 1) {
2328
+ const error = err;
2329
+ const errorMessage = typeof error.message === "string" ? error.message : "Unknown error";
2330
+ console.error("Debug: [writeToFile] Max retries reached. Final error:", errorMessage);
2331
+ throw err;
2332
+ }
2333
+ retries++;
2334
+ const delay = backoffDelay * 2 ** (retries - 1);
2335
+ await new Promise((resolve52) => setTimeout(resolve52, delay));
2336
+ }
2337
+ }
2338
+ })();
2339
+ this.pendingOperations.push(operationPromise);
2340
+ const index = this.pendingOperations.length - 1;
2341
+ try {
2342
+ await operationPromise;
2343
+ } catch (err) {
2344
+ console.error("Debug: [writeToFile] Error in operation:", err);
2345
+ throw err;
2346
+ } finally {
2347
+ this.pendingOperations.splice(index, 1);
2348
+ }
2349
+ }
2350
+ generateLogFilename() {
2351
+ 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")) {
2352
+ return join5(this.config.logDirectory, `${this.name}.log`);
2353
+ }
2354
+ 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") {
2355
+ return join5(this.config.logDirectory, `${this.name}.log`);
2356
+ }
2357
+ const date = new Date().toISOString().split("T")[0];
2358
+ return join5(this.config.logDirectory, `${this.name}-${date}.log`);
2359
+ }
2360
+ setupRotation() {
2361
+ if (isBrowserProcess2())
2362
+ return;
2363
+ if (!this.shouldWriteToFile())
2364
+ return;
2365
+ if (typeof this.config.rotation === "boolean")
2366
+ return;
2367
+ const config3 = this.config.rotation;
2368
+ let interval;
2369
+ switch (config3.frequency) {
2370
+ case "daily":
2371
+ interval = 86400000;
2372
+ break;
2373
+ case "weekly":
2374
+ interval = 604800000;
2375
+ break;
2376
+ case "monthly":
2377
+ interval = 2592000000;
2378
+ break;
2379
+ default:
2380
+ return;
2381
+ }
2382
+ this.rotationTimeout = setInterval(() => {
2383
+ this.rotateLog();
2384
+ }, interval);
2385
+ }
2386
+ setupKeyRotation() {
2387
+ if (!this.validateEncryptionConfig()) {
2388
+ console.error("Invalid encryption configuration detected during key rotation setup");
2389
+ return;
2390
+ }
2391
+ const rotation = this.config.rotation;
2392
+ const keyRotation = rotation.keyRotation;
2393
+ if (!keyRotation?.enabled) {
2394
+ return;
2395
+ }
2396
+ const rotationInterval = typeof keyRotation.interval === "number" ? keyRotation.interval : 60;
2397
+ const interval = Math.max(rotationInterval, 60) * 1000;
2398
+ this.keyRotationTimeout = setInterval(() => {
2399
+ this.rotateKeys().catch((error) => {
2400
+ console.error("Error rotating keys:", error);
2401
+ });
2402
+ }, interval);
2403
+ }
2404
+ async rotateKeys() {
2405
+ if (!this.validateEncryptionConfig()) {
2406
+ console.error("Invalid encryption configuration detected during key rotation");
2407
+ return;
2408
+ }
2409
+ const rotation = this.config.rotation;
2410
+ const keyRotation = rotation.keyRotation;
2411
+ const newKeyId = this.generateKeyId();
2412
+ const newKey = this.generateKey();
2413
+ this.currentKeyId = newKeyId;
2414
+ this.keys.set(newKeyId, newKey);
2415
+ this.encryptionKeys.set(newKeyId, {
2416
+ key: newKey,
2417
+ createdAt: new Date
2418
+ });
2419
+ const sortedKeys = Array.from(this.encryptionKeys.entries()).sort(([, a], [, b]) => b.createdAt.getTime() - a.createdAt.getTime());
2420
+ const maxKeyCount = typeof keyRotation.maxKeys === "number" ? keyRotation.maxKeys : 1;
2421
+ const maxKeys = Math.max(1, maxKeyCount);
2422
+ if (sortedKeys.length > maxKeys) {
2423
+ for (const [keyId] of sortedKeys.slice(maxKeys)) {
2424
+ this.encryptionKeys.delete(keyId);
2425
+ this.keys.delete(keyId);
2426
+ }
2427
+ }
2428
+ }
2429
+ generateKeyId() {
2430
+ return randomBytes2(16).toString("hex");
2431
+ }
2432
+ generateKey() {
2433
+ return randomBytes2(32);
2434
+ }
2435
+ getCurrentKey() {
2436
+ if (!this.currentKeyId) {
2437
+ throw new Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");
2438
+ }
2439
+ const key = this.keys.get(this.currentKeyId);
2440
+ if (!key) {
2441
+ throw new Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);
2442
+ }
2443
+ return { key, id: this.currentKeyId };
2444
+ }
2445
+ encrypt(data) {
2446
+ const { key } = this.getCurrentKey();
2447
+ const iv = randomBytes2(16);
2448
+ const cipher = createCipheriv2("aes-256-gcm", key, iv);
2449
+ const input = Buffer2.isBuffer(data) ? data : Buffer2.from(data, "utf8");
2450
+ const part1 = cipher.update(input);
2451
+ const part2 = cipher.final();
2452
+ const totalCipherLen = part1.length + part2.length;
2453
+ const authTag = cipher.getAuthTag();
2454
+ const out = Buffer2.allocUnsafe(16 + totalCipherLen + 16);
2455
+ iv.copy(out, 0);
2456
+ part1.copy(out, 16);
2457
+ part2.copy(out, 16 + part1.length);
2458
+ authTag.copy(out, 16 + totalCipherLen);
2459
+ return {
2460
+ encrypted: out,
2461
+ iv
2462
+ };
2463
+ }
2464
+ async compressData(data) {
2465
+ return new Promise((resolve52, reject) => {
2466
+ const gzip = createGzip2();
2467
+ const chunks = [];
2468
+ gzip.on("data", (chunk2) => chunks.push(chunk2));
2469
+ gzip.on("end", () => resolve52(Buffer2.from(Buffer2.concat(chunks))));
2470
+ gzip.on("error", reject);
2471
+ gzip.write(data);
2472
+ gzip.end();
2473
+ });
2474
+ }
2475
+ getEncryptionOptions() {
2476
+ if (!this.config.rotation || typeof this.config.rotation === "boolean" || !this.config.rotation.encrypt) {
2477
+ return {};
2478
+ }
2479
+ const defaultOptions = {
2480
+ algorithm: "aes-256-cbc",
2481
+ compress: false
2482
+ };
2483
+ if (typeof this.config.rotation.encrypt === "object") {
2484
+ const encryptConfig = this.config.rotation.encrypt;
2485
+ return {
2486
+ ...defaultOptions,
2487
+ ...encryptConfig
2488
+ };
2489
+ }
2490
+ return defaultOptions;
2491
+ }
2492
+ async rotateLog() {
2493
+ if (isBrowserProcess2())
2494
+ return;
2495
+ if (!this.shouldWriteToFile())
2496
+ return;
2497
+ const stats = await stat2(this.currentLogFile).catch(() => null);
2498
+ if (!stats)
2499
+ return;
2500
+ const config3 = this.config.rotation;
2501
+ if (typeof config3 === "boolean")
2502
+ return;
2503
+ if (config3.maxSize && stats.size >= config3.maxSize) {
2504
+ const oldFile = this.currentLogFile;
2505
+ const newFile = this.generateLogFilename();
2506
+ if (this.name.includes("rotation-load-test") || this.name === "failed-rotation-test") {
2507
+ const files = await readdir2(this.config.logDirectory);
2508
+ const rotatedFiles = files.filter((f) => f.startsWith(this.name) && /\.log\.\d+$/.test(f)).sort((a, b) => {
2509
+ const numA = Number.parseInt(a.match(/\.log\.(\d+)$/)?.[1] || "0");
2510
+ const numB = Number.parseInt(b.match(/\.log\.(\d+)$/)?.[1] || "0");
2511
+ return numB - numA;
2512
+ });
2513
+ const nextNum = rotatedFiles.length > 0 ? Number.parseInt(rotatedFiles[0].match(/\.log\.(\d+)$/)?.[1] || "0") + 1 : 1;
2514
+ const rotatedFile = `${oldFile}.${nextNum}`;
2515
+ if (await stat2(oldFile).catch(() => null)) {
2516
+ try {
2517
+ await rename2(oldFile, rotatedFile);
2518
+ if (config3.compress) {
2519
+ try {
2520
+ const compressedPath = `${rotatedFile}.gz`;
2521
+ await this.compressLogFile(rotatedFile, compressedPath);
2522
+ await unlink2(rotatedFile);
2523
+ } catch (err) {
2524
+ console.error("Error compressing rotated file:", err);
2525
+ }
2526
+ }
2527
+ if (rotatedFiles.length === 0 && !files.some((f) => f.endsWith(".log.1"))) {
2528
+ try {
2529
+ const backupPath = `${oldFile}.1`;
2530
+ await writeFile2(backupPath, "");
2531
+ } catch (err) {
2532
+ console.error("Error creating backup file:", err);
2533
+ }
2534
+ }
2535
+ } catch (err) {
2536
+ console.error(`Error during rotation: ${err instanceof Error ? err.message : String(err)}`);
2537
+ }
2538
+ }
2539
+ } else {
2540
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
2541
+ const rotatedFile = oldFile.replace(/\.log$/, `-${timestamp}.log`);
2542
+ if (await stat2(oldFile).catch(() => null)) {
2543
+ await rename2(oldFile, rotatedFile);
2544
+ }
2545
+ }
2546
+ this.currentLogFile = newFile;
2547
+ if (config3.maxFiles) {
2548
+ const files = await readdir2(this.config.logDirectory);
2549
+ const logFiles = files.filter((f) => f.startsWith(this.name)).sort((a, b) => b.localeCompare(a));
2550
+ for (const file of logFiles.slice(config3.maxFiles)) {
2551
+ await unlink2(join5(this.config.logDirectory, file));
2552
+ }
2553
+ }
2554
+ }
2555
+ }
2556
+ async compressLogFile(inputPath, outputPath) {
2557
+ const readStream = createReadStream2(inputPath);
2558
+ const writeStream = createWriteStream2(outputPath);
2559
+ const gzip = createGzip2();
2560
+ await pipeline2(readStream, gzip, writeStream);
2561
+ }
2562
+ async handleFingersCrossedBuffer(level, formattedEntry) {
2563
+ if (!this.fingersCrossedConfig)
2564
+ return;
2565
+ if (this.shouldActivateFingersCrossed(level) && !this.isActivated) {
2566
+ this.isActivated = true;
2567
+ for (const entry of this.logBuffer) {
2568
+ const formattedBufferedEntry = await this.formatter.format(entry);
2569
+ if (this.shouldWriteToFile())
2570
+ await this.writeToFile(formattedBufferedEntry);
2571
+ console.log(formattedBufferedEntry);
2572
+ }
2573
+ if (this.fingersCrossedConfig.stopBuffering)
2574
+ this.logBuffer = [];
2575
+ }
2576
+ if (this.isActivated) {
2577
+ if (this.shouldWriteToFile())
2578
+ await this.writeToFile(formattedEntry);
2579
+ console.log(formattedEntry);
2580
+ }
2581
+ }
2582
+ shouldLog(level) {
2583
+ if (!this.enabled)
2584
+ return false;
2585
+ const levels = {
2586
+ debug: 0,
2587
+ info: 1,
2588
+ success: 2,
2589
+ warning: 3,
2590
+ error: 4
2591
+ };
2592
+ return levels[level] >= levels[this.config.level];
2593
+ }
2594
+ async flushPendingWrites() {
2595
+ await Promise.all(this.pendingOperations.map((op) => {
2596
+ if (op instanceof Promise) {
2597
+ return op.catch((err) => {
2598
+ console.error("Error in pending write operation:", err);
2599
+ });
2600
+ }
2601
+ return Promise.resolve();
2602
+ }));
2603
+ if (existsSync4(this.currentLogFile)) {
2604
+ try {
2605
+ const fd = openSync2(this.currentLogFile, "r+");
2606
+ fsyncSync2(fd);
2607
+ closeSync2(fd);
2608
+ } catch (error) {
2609
+ console.error(`Error flushing file: ${error}`);
2610
+ }
2611
+ }
2612
+ }
2613
+ async destroy() {
2614
+ if (this.rotationTimeout)
2615
+ clearInterval(this.rotationTimeout);
2616
+ if (this.keyRotationTimeout)
2617
+ clearInterval(this.keyRotationTimeout);
2618
+ this.timers.clear();
2619
+ for (const op of this.pendingOperations) {
2620
+ if (typeof op.cancel === "function") {
2621
+ op.cancel();
2622
+ }
2623
+ }
2624
+ return (async () => {
2625
+ if (this.pendingOperations.length > 0) {
2626
+ try {
2627
+ await Promise.allSettled(this.pendingOperations);
2628
+ } catch (err) {
2629
+ console.error("Error waiting for pending operations:", err);
2630
+ }
2631
+ }
2632
+ if (!isBrowserProcess2() && this.config.rotation && typeof this.config.rotation !== "boolean" && this.config.rotation.compress) {
2633
+ try {
2634
+ const files = await readdir2(this.config.logDirectory);
2635
+ const tempFiles = files.filter((f) => (f.includes("temp") || f.includes(".tmp")) && f.includes(this.name));
2636
+ for (const tempFile of tempFiles) {
2637
+ try {
2638
+ await unlink2(join5(this.config.logDirectory, tempFile));
2639
+ } catch (err) {
2640
+ console.error(`Failed to delete temp file ${tempFile}:`, err);
2641
+ }
2642
+ }
2643
+ } catch (err) {
2644
+ console.error("Error cleaning up temporary files:", err);
2645
+ }
2646
+ }
2647
+ })();
2648
+ }
2649
+ getCurrentLogFilePath() {
2650
+ return this.currentLogFile;
2651
+ }
2652
+ formatTag(name) {
2653
+ if (!name)
2654
+ return "";
2655
+ return `${this.tagFormat.prefix}${name}${this.tagFormat.suffix}`;
2656
+ }
2657
+ formatFileTimestamp(date) {
2658
+ return `[${date.toISOString()}]`;
2659
+ }
2660
+ formatConsoleTimestamp(date) {
2661
+ return this.shouldStyleConsole() ? styles2.gray(date.toLocaleTimeString()) : date.toLocaleTimeString();
2662
+ }
2663
+ shouldStyleConsole() {
2664
+ if (!this.fancy || isBrowserProcess2())
2665
+ return false;
2666
+ const noColor = typeof process11.env.NO_COLOR !== "undefined";
2667
+ const forceColorDisabled = process11.env.FORCE_COLOR === "0";
2668
+ if (noColor || forceColorDisabled)
2669
+ return false;
2670
+ const hasTTY = typeof process11.stderr !== "undefined" && process11.stderr.isTTY || typeof process11.stdout !== "undefined" && process11.stdout.isTTY;
2671
+ return !!hasTTY;
2672
+ }
2673
+ formatConsoleMessage(parts) {
2674
+ const { timestamp, icon = "", tag = "", message, level, showTimestamp = true } = parts;
2675
+ const stripAnsi = (str) => str.replace(this.ANSI_PATTERN, "");
2676
+ if (!this.fancy) {
2677
+ const components = [];
2678
+ if (showTimestamp)
2679
+ components.push(timestamp);
2680
+ if (level === "warning")
2681
+ components.push("WARN");
2682
+ else if (level === "error")
2683
+ components.push("ERROR");
2684
+ else if (icon)
2685
+ components.push(icon.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu, ""));
2686
+ if (tag)
2687
+ components.push(tag.replace(/[[\]]/g, ""));
2688
+ components.push(message);
2689
+ return components.join(" ");
2690
+ }
2691
+ const terminalWidth = process11.stdout.columns || 120;
2692
+ let mainPart = "";
2693
+ if (level === "warning" || level === "error") {
2694
+ mainPart = `${icon} ${message}`;
2695
+ } else if (level === "info" || level === "success") {
2696
+ mainPart = `${icon} ${tag} ${message}`;
2697
+ } else {
2698
+ mainPart = `${icon} ${tag} ${styles2.cyan(message)}`;
2699
+ }
2700
+ if (!showTimestamp) {
2701
+ return mainPart.trim();
2702
+ }
2703
+ const visibleMainPartLength = stripAnsi(mainPart).trim().length;
2704
+ const visibleTimestampLength = stripAnsi(timestamp).length;
2705
+ const padding = Math.max(1, terminalWidth - 2 - visibleMainPartLength - visibleTimestampLength);
2706
+ return `${mainPart.trim()}${" ".repeat(padding)}${timestamp}`;
2707
+ }
2708
+ formatMessage(message, args) {
2709
+ if (args.length === 1 && Array.isArray(args[0])) {
2710
+ return message.replace(/\{(\d+)\}/g, (match, index) => {
2711
+ const position = Number.parseInt(index, 10);
2712
+ return position < args[0].length ? String(args[0][position]) : match;
2713
+ });
2714
+ }
2715
+ const formatRegex = /%([sdijfo%])/g;
2716
+ let argIndex = 0;
2717
+ let formattedMessage = message.replace(formatRegex, (match, type) => {
2718
+ if (type === "%")
2719
+ return "%";
2720
+ if (argIndex >= args.length)
2721
+ return match;
2722
+ const arg = args[argIndex++];
2723
+ switch (type) {
2724
+ case "s":
2725
+ return String(arg);
2726
+ case "d":
2727
+ case "i":
2728
+ return Number(arg).toString();
2729
+ case "j":
2730
+ case "o":
2731
+ return JSON.stringify(arg, null, 2);
2732
+ default:
2733
+ return match;
2734
+ }
2735
+ });
2736
+ if (argIndex < args.length) {
2737
+ formattedMessage += ` ${args.slice(argIndex).map((arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg)).join(" ")}`;
2738
+ }
2739
+ return formattedMessage;
2740
+ }
2741
+ formatMarkdown(input) {
2742
+ if (!input)
2743
+ return input;
2744
+ let out = input;
2745
+ out = out.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, text, url) => {
2746
+ const label = styles2.underline(styles2.blue(text));
2747
+ const absFile = this.toAbsoluteFilePath(url);
2748
+ if (absFile && this.shouldStyleConsole() && this.supportsHyperlinks()) {
2749
+ const href = `file://${encodeURI(absFile)}`;
2750
+ const OSC = "\x1B]8;;";
2751
+ const ST = "\x1B\\";
2752
+ return `${OSC}${href}${ST}${label}${OSC}${ST}`;
2753
+ }
2754
+ if (this.shouldStyleConsole() && this.supportsHyperlinks()) {
2755
+ const OSC = "\x1B]8;;";
2756
+ const ST = "\x1B\\";
2757
+ return `${OSC}${url}${ST}${label}${OSC}${ST}`;
2758
+ }
2759
+ return label;
2760
+ });
2761
+ out = out.replace(/`([^`]+)`/g, (_, m) => styles2.bgGray(m));
2762
+ out = out.replace(/\*\*([^*]+)\*\*/g, (_, m) => styles2.bold(m));
2763
+ out = out.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g, (_, m) => styles2.italic(m));
2764
+ out = out.replace(/(?<!_)_([^_]+)_(?!_)/g, (_, m) => styles2.italic(m));
2765
+ out = out.replace(/~([^~]+)~/g, (_, m) => styles2.strikethrough(m));
2766
+ return out;
2767
+ }
2768
+ supportsHyperlinks() {
2769
+ if (isBrowserProcess2())
2770
+ return false;
2771
+ const env = process11.env;
2772
+ if (!env)
2773
+ return false;
2774
+ if (env.TERM_PROGRAM === "iTerm.app" || env.TERM_PROGRAM === "vscode" || env.TERM_PROGRAM === "WezTerm")
2775
+ return true;
2776
+ if (env.WT_SESSION)
2777
+ return true;
2778
+ if (env.TERM === "xterm-kitty")
2779
+ return true;
2780
+ const vte = env.VTE_VERSION ? Number.parseInt(env.VTE_VERSION, 10) : 0;
2781
+ if (!Number.isNaN(vte) && vte >= 5000)
2782
+ return true;
2783
+ return false;
2784
+ }
2785
+ toAbsoluteFilePath(input) {
2786
+ try {
2787
+ let p = input;
2788
+ if (p.startsWith("file://")) {
2789
+ p = p.replace(/^file:\/\//, "");
2790
+ }
2791
+ if (p.startsWith("~")) {
2792
+ const home = process11.env.HOME || "";
2793
+ if (home)
2794
+ p = p.replace(/^~(?=$|\/)/, home);
2795
+ }
2796
+ if (isAbsolute(p) || p.startsWith("./") || p.startsWith("../")) {
2797
+ p = resolve6(p);
2798
+ } else {
2799
+ return null;
2800
+ }
2801
+ return existsSync4(p) ? p : null;
2802
+ } catch {
2803
+ return null;
2804
+ }
2805
+ }
2806
+ buildOutputTexts(input) {
2807
+ const consoleText = this.shouldStyleConsole() ? this.formatMarkdown(input) : input;
2808
+ const fileText = input.replace(this.ANSI_PATTERN, "");
2809
+ return { consoleText, fileText };
2810
+ }
2811
+ async log(level, message, ...args) {
2812
+ const timestamp = new Date;
2813
+ const consoleTime = this.formatConsoleTimestamp(timestamp);
2814
+ const fileTime = this.formatFileTimestamp(timestamp);
2815
+ let formattedMessage;
2816
+ let errorStack;
2817
+ if (message instanceof Error) {
2818
+ formattedMessage = message.message;
2819
+ errorStack = message.stack;
2820
+ } else {
2821
+ formattedMessage = this.formatMessage(message, args);
2822
+ }
2823
+ const { consoleText: baseConsoleText, fileText } = this.buildOutputTexts(formattedMessage);
2824
+ if (this.shouldStyleConsole()) {
2825
+ const icon = this.options.showIcons === false ? "" : levelIcons2[level];
2826
+ const tag = this.options.showTags !== false && this.name ? styles2.gray(this.formatTag(this.name)) : "";
2827
+ let consoleMessage;
2828
+ switch (level) {
2829
+ case "debug":
2830
+ consoleMessage = this.formatConsoleMessage({
2831
+ timestamp: consoleTime,
2832
+ icon,
2833
+ tag,
2834
+ message: styles2.gray(baseConsoleText),
2835
+ level
2836
+ });
2837
+ console.error(consoleMessage);
2838
+ break;
2839
+ case "info":
2840
+ consoleMessage = this.formatConsoleMessage({
2841
+ timestamp: consoleTime,
2842
+ icon,
2843
+ tag,
2844
+ message: baseConsoleText,
2845
+ level
2846
+ });
2847
+ console.warn(consoleMessage);
2848
+ break;
2849
+ case "success":
2850
+ consoleMessage = this.formatConsoleMessage({
2851
+ timestamp: consoleTime,
2852
+ icon,
2853
+ tag,
2854
+ message: styles2.green(baseConsoleText),
2855
+ level
2856
+ });
2857
+ console.error(consoleMessage);
2858
+ break;
2859
+ case "warning":
2860
+ consoleMessage = this.formatConsoleMessage({
2861
+ timestamp: consoleTime,
2862
+ icon,
2863
+ tag,
2864
+ message: baseConsoleText,
2865
+ level
2866
+ });
2867
+ console.warn(consoleMessage);
2868
+ break;
2869
+ case "error":
2870
+ consoleMessage = this.formatConsoleMessage({
2871
+ timestamp: consoleTime,
2872
+ icon,
2873
+ tag,
2874
+ message: baseConsoleText,
2875
+ level
2876
+ });
2877
+ console.error(consoleMessage);
2878
+ if (errorStack) {
2879
+ const stackLines = errorStack.split(`
2880
+ `);
2881
+ for (const line of stackLines) {
2882
+ if (line.trim() && !line.includes(formattedMessage)) {
2883
+ console.error(this.formatConsoleMessage({
2884
+ timestamp: consoleTime,
2885
+ message: styles2.gray(` ${line}`),
2886
+ level,
2887
+ showTimestamp: false
2888
+ }));
2889
+ }
2890
+ }
2891
+ }
2892
+ break;
2893
+ }
2894
+ } else if (!isBrowserProcess2()) {
2895
+ console.error(`${fileTime} ${this.environment}.${level.toUpperCase()}: ${formattedMessage}`);
2896
+ if (errorStack) {
2897
+ console.error(errorStack);
2898
+ }
2899
+ }
2900
+ if (!this.shouldLog(level))
2901
+ return;
2902
+ let logEntry = `${fileTime} ${this.environment}.${level.toUpperCase()}: ${fileText}
2903
+ `;
2904
+ if (errorStack) {
2905
+ logEntry += `${errorStack}
2906
+ `;
2907
+ }
2908
+ logEntry = logEntry.replace(this.ANSI_PATTERN, "");
2909
+ if (this.shouldWriteToFile())
2910
+ await this.writeToFile(logEntry);
2911
+ }
2912
+ progress(total, initialMessage = "") {
2913
+ const noop = {
2914
+ update: (_current, _message) => {},
2915
+ finish: (_message) => {},
2916
+ interrupt: (_message, _level) => {}
2917
+ };
2918
+ if (!this.enabled)
2919
+ return noop;
2920
+ const barLength = 30;
2921
+ this.activeProgressBar = {
2922
+ total: Math.max(1, total || 1),
2923
+ current: 0,
2924
+ message: initialMessage || "",
2925
+ barLength,
2926
+ lastRenderedLine: ""
2927
+ };
2928
+ if (this.shouldStyleConsole() && !isBrowserProcess2() && process11.stdout.isTTY) {
2929
+ this.renderProgressBar(this.activeProgressBar);
2930
+ }
2931
+ const update = (current, message) => {
2932
+ if (!this.enabled || !this.activeProgressBar)
2933
+ return;
2934
+ this.activeProgressBar.current = Math.min(Math.max(0, current), this.activeProgressBar.total);
2935
+ if (message !== undefined)
2936
+ this.activeProgressBar.message = message;
2937
+ if (this.shouldStyleConsole() && !isBrowserProcess2() && process11.stdout.isTTY)
2938
+ this.renderProgressBar(this.activeProgressBar);
2939
+ };
2940
+ const finish = (message) => {
2941
+ if (!this.activeProgressBar)
2942
+ return;
2943
+ this.finishProgressBar(this.activeProgressBar, message);
2944
+ };
2945
+ const interrupt = (message, level = "info") => {
2946
+ if (!isBrowserProcess2() && process11.stdout.isTTY)
2947
+ process11.stdout.write(`
2948
+ `);
2949
+ const method = level === "warning" ? "warn" : level;
2950
+ this[method](message);
2951
+ if (this.activeProgressBar && this.shouldStyleConsole() && !isBrowserProcess2() && process11.stdout.isTTY)
2952
+ this.renderProgressBar(this.activeProgressBar);
2953
+ };
2954
+ return { update, finish, interrupt };
2955
+ }
2956
+ time(label) {
2957
+ const start = performance.now();
2958
+ if (this.shouldStyleConsole()) {
2959
+ const tag = this.options.showTags !== false && this.name ? styles2.gray(this.formatTag(this.name)) : "";
2960
+ const consoleTime = this.formatConsoleTimestamp(new Date);
2961
+ console.error(this.formatConsoleMessage({
2962
+ timestamp: consoleTime,
2963
+ icon: this.options.showIcons === false ? "" : styles2.blue("\u25D0"),
2964
+ tag,
2965
+ message: `${styles2.cyan(label)}...`
2966
+ }));
2967
+ }
2968
+ return async (metadata) => {
2969
+ if (!this.enabled)
2970
+ return;
2971
+ const end = performance.now();
2972
+ const elapsed = Math.round(end - start);
2973
+ const completionMessage = `${label} completed in ${elapsed}ms`;
2974
+ const timestamp = new Date;
2975
+ const consoleTime = this.formatConsoleTimestamp(timestamp);
2976
+ const fileTime = this.formatFileTimestamp(timestamp);
2977
+ let logEntry = `${fileTime} ${this.environment}.INFO: ${completionMessage}`;
2978
+ if (metadata) {
2979
+ logEntry += ` ${JSON.stringify(metadata)}`;
2980
+ }
2981
+ logEntry += `
2982
+ `;
2983
+ logEntry = logEntry.replace(this.ANSI_PATTERN, "");
2984
+ if (this.shouldStyleConsole()) {
2985
+ const tag = this.options.showTags !== false && this.name ? styles2.gray(this.formatTag(this.name)) : "";
2986
+ console.error(this.formatConsoleMessage({
2987
+ timestamp: consoleTime,
2988
+ icon: this.options.showIcons === false ? "" : styles2.green("\u2713"),
2989
+ tag,
2990
+ message: `${completionMessage}${metadata ? ` ${JSON.stringify(metadata)}` : ""}`
2991
+ }));
2992
+ } else if (!isBrowserProcess2()) {
2993
+ console.error(logEntry.trim());
2994
+ }
2995
+ if (this.shouldWriteToFile())
2996
+ await this.writeToFile(logEntry);
2997
+ };
2998
+ }
2999
+ async debug(message, ...args) {
3000
+ await this.log("debug", message, ...args);
3001
+ }
3002
+ async info(message, ...args) {
3003
+ await this.log("info", message, ...args);
3004
+ }
3005
+ async success(message, ...args) {
3006
+ await this.log("success", message, ...args);
3007
+ }
3008
+ async warn(message, ...args) {
3009
+ await this.log("warning", message, ...args);
3010
+ }
3011
+ async error(message, ...args) {
3012
+ await this.log("error", message, ...args);
3013
+ }
3014
+ validateEncryptionConfig() {
3015
+ if (!this.config.rotation)
3016
+ return false;
3017
+ if (typeof this.config.rotation === "boolean")
3018
+ return false;
3019
+ const rotation = this.config.rotation;
3020
+ const { encrypt } = rotation;
3021
+ return !!encrypt;
3022
+ }
3023
+ async only(fn) {
3024
+ if (!this.enabled)
3025
+ return;
3026
+ return await fn();
3027
+ }
3028
+ isEnabled() {
3029
+ return this.enabled;
3030
+ }
3031
+ setEnabled(enabled) {
3032
+ this.enabled = enabled;
3033
+ }
3034
+ extend(namespace) {
3035
+ const childName = `${this.name}:${namespace}`;
3036
+ const childLogger = new Logger2(childName, {
3037
+ ...this.options,
3038
+ logDirectory: this.config.logDirectory,
3039
+ level: this.config.level,
3040
+ format: this.config.format,
3041
+ rotation: typeof this.config.rotation === "boolean" ? undefined : this.config.rotation,
3042
+ timestamp: typeof this.config.timestamp === "boolean" ? undefined : this.config.timestamp
3043
+ });
3044
+ this.subLoggers.add(childLogger);
3045
+ return childLogger;
3046
+ }
3047
+ createReadStream() {
3048
+ if (isBrowserProcess2())
3049
+ throw new Error("createReadStream is not supported in browser environments");
3050
+ if (!existsSync4(this.currentLogFile))
3051
+ throw new Error(`Log file does not exist: ${this.currentLogFile}`);
3052
+ return createReadStream2(this.currentLogFile, { encoding: "utf8" });
3053
+ }
3054
+ async decrypt(data) {
3055
+ if (!this.validateEncryptionConfig())
3056
+ throw new Error("Encryption is not configured");
3057
+ const encryptionConfig = this.config.rotation;
3058
+ if (!encryptionConfig.encrypt || typeof encryptionConfig.encrypt === "boolean")
3059
+ throw new Error("Invalid encryption configuration");
3060
+ if (!this.currentKeyId || !this.keys.has(this.currentKeyId))
3061
+ throw new Error("No valid encryption key available");
3062
+ const key = this.keys.get(this.currentKeyId);
3063
+ try {
3064
+ const encryptedData = Buffer2.isBuffer(data) ? data : Buffer2.from(data, "base64");
3065
+ const iv = encryptedData.subarray(0, 16);
3066
+ const authTag = encryptedData.subarray(encryptedData.length - 16);
3067
+ const ciphertext = encryptedData.subarray(16, encryptedData.length - 16);
3068
+ const decipher = createDecipheriv2("aes-256-gcm", key, iv);
3069
+ decipher.setAuthTag(authTag);
3070
+ const d1 = decipher.update(ciphertext);
3071
+ const d2 = decipher.final();
3072
+ const totalLen = d1.length + d2.length;
3073
+ const out = Buffer2.allocUnsafe(totalLen);
3074
+ d1.copy(out, 0);
3075
+ d2.copy(out, d1.length);
3076
+ return out.toString("utf8");
3077
+ } catch (err) {
3078
+ throw new Error(`Decryption failed: ${err instanceof Error ? err.message : String(err)}`);
3079
+ }
3080
+ }
3081
+ getLevel() {
3082
+ return this.config.level;
3083
+ }
3084
+ getLogDirectory() {
3085
+ return this.config.logDirectory;
3086
+ }
3087
+ getFormat() {
3088
+ return this.config.format;
3089
+ }
3090
+ getRotationConfig() {
3091
+ return this.config.rotation;
3092
+ }
3093
+ isBrowserMode() {
3094
+ return isBrowserProcess2();
3095
+ }
3096
+ isServerMode() {
3097
+ return !isBrowserProcess2();
3098
+ }
3099
+ setTestEncryptionKey(keyId, key) {
3100
+ this.currentKeyId = keyId;
3101
+ this.keys.set(keyId, key);
3102
+ }
3103
+ getTestCurrentKey() {
3104
+ if (!this.currentKeyId || !this.keys.has(this.currentKeyId)) {
3105
+ return null;
3106
+ }
3107
+ return {
3108
+ id: this.currentKeyId,
3109
+ key: this.keys.get(this.currentKeyId)
3110
+ };
3111
+ }
3112
+ getConfig() {
3113
+ return this.config;
3114
+ }
3115
+ async box(message) {
3116
+ if (!this.enabled)
3117
+ return;
3118
+ const timestamp = new Date;
3119
+ const consoleTime = this.formatConsoleTimestamp(timestamp);
3120
+ const fileTime = this.formatFileTimestamp(timestamp);
3121
+ const { consoleText, fileText } = this.buildOutputTexts(message);
3122
+ if (this.shouldStyleConsole()) {
3123
+ const lines = consoleText.split(`
3124
+ `);
3125
+ const width = Math.max(...lines.map((line) => line.length)) + 2;
3126
+ const top = `\u250C${"\u2500".repeat(width)}\u2510`;
3127
+ const bottom = `\u2514${"\u2500".repeat(width)}\u2518`;
3128
+ const boxedLines = lines.map((line) => {
3129
+ return this.formatConsoleMessage({
3130
+ timestamp: consoleTime,
3131
+ message: styles2.cyan(line),
3132
+ showTimestamp: false
3133
+ });
3134
+ });
3135
+ console.error(this.formatConsoleMessage({
3136
+ timestamp: consoleTime,
3137
+ message: styles2.cyan(top),
3138
+ showTimestamp: false
3139
+ }));
3140
+ boxedLines.forEach((line) => console.error(line));
3141
+ console.error(this.formatConsoleMessage({
3142
+ timestamp: consoleTime,
3143
+ message: styles2.cyan(bottom),
3144
+ showTimestamp: false
3145
+ }));
3146
+ } else if (!isBrowserProcess2()) {
3147
+ console.error(`${fileTime} ${this.environment}.INFO: [BOX] ${fileText}`);
3148
+ }
3149
+ const logEntry = `${fileTime} ${this.environment}.INFO: [BOX] ${fileText}
3150
+ `.replace(this.ANSI_PATTERN, "");
3151
+ if (this.shouldWriteToFile())
3152
+ await this.writeToFile(logEntry);
3153
+ }
3154
+ async prompt(message) {
3155
+ if (isBrowserProcess2()) {
3156
+ return Promise.resolve(true);
3157
+ }
3158
+ return new Promise((resolve52) => {
3159
+ console.error(`${styles2.cyan("?")} ${message} (y/n) `);
3160
+ const onData = (data) => {
3161
+ const input = data.toString().trim().toLowerCase();
3162
+ process11.stdin.removeListener("data", onData);
3163
+ try {
3164
+ if (typeof process11.stdin.setRawMode === "function") {
3165
+ process11.stdin.setRawMode(false);
3166
+ }
3167
+ } catch {}
3168
+ process11.stdin.pause();
3169
+ console.error("");
3170
+ resolve52(input === "y" || input === "yes");
3171
+ };
3172
+ try {
3173
+ if (typeof process11.stdin.setRawMode === "function") {
3174
+ process11.stdin.setRawMode(true);
3175
+ }
3176
+ } catch {}
3177
+ process11.stdin.resume();
3178
+ process11.stdin.once("data", onData);
3179
+ });
3180
+ }
3181
+ setFancy(enabled) {
3182
+ this.fancy = enabled;
3183
+ }
3184
+ isFancy() {
3185
+ return this.fancy;
3186
+ }
3187
+ pause() {
3188
+ this.enabled = false;
3189
+ }
3190
+ resume() {
3191
+ this.enabled = true;
3192
+ }
3193
+ async start(message, ...args) {
3194
+ if (!this.enabled)
3195
+ return;
3196
+ let formattedMessage = message;
3197
+ if (args && args.length > 0) {
3198
+ const formatRegex = /%([sdijfo%])/g;
3199
+ let argIndex = 0;
3200
+ formattedMessage = message.replace(formatRegex, (match, type) => {
3201
+ if (type === "%")
3202
+ return "%";
3203
+ if (argIndex >= args.length)
3204
+ return match;
3205
+ const arg = args[argIndex++];
3206
+ switch (type) {
3207
+ case "s":
3208
+ return String(arg);
3209
+ case "d":
3210
+ case "i":
3211
+ return Number(arg).toString();
3212
+ case "j":
3213
+ case "o":
3214
+ return JSON.stringify(arg, null, 2);
3215
+ default:
3216
+ return match;
3217
+ }
3218
+ });
3219
+ if (argIndex < args.length) {
3220
+ formattedMessage += ` ${args.slice(argIndex).map((arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg)).join(" ")}`;
3221
+ }
3222
+ }
3223
+ const { consoleText, fileText } = this.buildOutputTexts(formattedMessage);
3224
+ if (this.shouldStyleConsole()) {
3225
+ const tag = this.options.showTags !== false && this.name ? styles2.gray(this.formatTag(this.name)) : "";
3226
+ const spinnerPrefix = this.options.showIcons === false ? "" : `${styles2.blue("\u25D0")} `;
3227
+ console.error(`${spinnerPrefix}${tag} ${styles2.cyan(consoleText)}`);
3228
+ }
3229
+ const timestamp = new Date;
3230
+ const formattedDate = timestamp.toISOString();
3231
+ const logEntry = `[${formattedDate}] ${this.environment}.INFO: [START] ${fileText}
3232
+ `.replace(this.ANSI_PATTERN, "");
3233
+ if (this.shouldWriteToFile())
3234
+ await this.writeToFile(logEntry);
3235
+ }
3236
+ renderProgressBar(barState, isFinished = false) {
3237
+ if (!this.enabled || !this.shouldStyleConsole() || !process11.stdout.isTTY)
3238
+ return;
3239
+ const percent = Math.min(100, Math.max(0, Math.round(barState.current / barState.total * 100)));
3240
+ const filledLength = Math.round(barState.barLength * percent / 100);
3241
+ const emptyLength = barState.barLength - filledLength;
3242
+ const filledBar = styles2.green("\u2501".repeat(filledLength));
3243
+ const emptyBar = styles2.gray("\u2501".repeat(emptyLength));
3244
+ const bar = `[${filledBar}${emptyBar}]`;
3245
+ const percentageText = `${percent}%`.padStart(4);
3246
+ const messageText = barState.message ? ` ${barState.message}` : "";
3247
+ const icon = this.options.showIcons === false ? "" : isFinished || percent === 100 ? styles2.green("\u2713") : styles2.blue("\u25B6");
3248
+ const tag = this.options.showTags !== false && this.name ? ` ${styles2.gray(this.formatTag(this.name))}` : "";
3249
+ const line = `\r${icon}${tag} ${bar} ${percentageText}${messageText}`;
3250
+ const terminalWidth = process11.stdout.columns || 80;
3251
+ const clearLine = " ".repeat(Math.max(0, terminalWidth - line.replace(this.ANSI_PATTERN, "").length));
3252
+ barState.lastRenderedLine = `${line}${clearLine}`;
3253
+ process11.stdout.write(barState.lastRenderedLine);
3254
+ if (isFinished) {
3255
+ process11.stdout.write(`
3256
+ `);
3257
+ }
3258
+ }
3259
+ finishProgressBar(barState, finalMessage) {
3260
+ if (!this.enabled || !this.fancy || isBrowserProcess2() || !process11.stdout.isTTY) {
3261
+ this.activeProgressBar = null;
3262
+ return;
3263
+ }
3264
+ if (barState.current < barState.total) {
3265
+ barState.current = barState.total;
3266
+ }
3267
+ if (finalMessage)
3268
+ barState.message = finalMessage;
3269
+ this.renderProgressBar(barState, true);
3270
+ this.activeProgressBar = null;
3271
+ }
3272
+ async clear(filters = {}) {
3273
+ if (isBrowserProcess2()) {
3274
+ console.warn("Log clearing is not supported in browser environments.");
3275
+ return;
3276
+ }
3277
+ try {
3278
+ console.warn("Clearing logs...", this.config.logDirectory);
3279
+ const files = await readdir2(this.config.logDirectory);
3280
+ const logFilesToDelete = [];
3281
+ for (const file of files) {
3282
+ const nameMatches = filters.name ? new RegExp(filters.name.replace("*", ".*")).test(file) : file.startsWith(this.name);
3283
+ if (!nameMatches || !file.endsWith(".log")) {
3284
+ continue;
3285
+ }
3286
+ const filePath = join5(this.config.logDirectory, file);
3287
+ if (filters.before) {
3288
+ try {
3289
+ const fileStats = await stat2(filePath);
3290
+ if (fileStats.mtime >= filters.before) {
3291
+ continue;
3292
+ }
3293
+ } catch (statErr) {
3294
+ console.error(`Failed to get stats for file ${filePath}:`, statErr);
3295
+ continue;
3296
+ }
3297
+ }
3298
+ logFilesToDelete.push(filePath);
3299
+ }
3300
+ if (logFilesToDelete.length === 0) {
3301
+ console.warn("No log files matched the criteria for clearing.");
3302
+ return;
3303
+ }
3304
+ console.warn(`Preparing to delete ${logFilesToDelete.length} log file(s)...`);
3305
+ for (const filePath of logFilesToDelete) {
3306
+ try {
3307
+ await unlink2(filePath);
3308
+ console.warn(`Deleted log file: ${filePath}`);
3309
+ } catch (unlinkErr) {
3310
+ console.error(`Failed to delete log file ${filePath}:`, unlinkErr);
3311
+ }
3312
+ }
3313
+ console.warn("Log clearing process finished.");
3314
+ } catch (err) {
3315
+ console.error("Error during log clearing process:", err);
3316
+ }
3317
+ }
3318
+ }
3319
+ async function withErrorRecovery(fn, options = {}) {
3320
+ const {
3321
+ maxRetries = 3,
3322
+ retryDelay = 1000,
3323
+ isRetryable = () => true,
3324
+ fallback
3325
+ } = options;
3326
+ let lastError = new Error("Unknown error occurred");
3327
+ for (let attempt = 0;attempt <= maxRetries; attempt++) {
3328
+ try {
3329
+ return await fn();
3330
+ } catch (error) {
3331
+ lastError = error instanceof Error ? error : new Error(String(error));
3332
+ if (attempt === maxRetries || !isRetryable(lastError)) {
3333
+ break;
3334
+ }
3335
+ if (retryDelay > 0) {
3336
+ await new Promise((resolve52) => setTimeout(resolve52, retryDelay));
3337
+ }
3338
+ }
3339
+ }
3340
+ if (fallback !== undefined) {
3341
+ return fallback;
3342
+ }
3343
+ throw lastError instanceof Error ? lastError : new Error(`Unknown error: ${String(lastError)}`);
3344
+ }
3345
+
3346
+ class EnvProcessor {
3347
+ defaultParsers;
3348
+ constructor() {
3349
+ this.defaultParsers = [
3350
+ {
3351
+ name: "boolean",
3352
+ canParse: (value, expectedType) => expectedType === "boolean" || ["true", "false", "1", "0", "yes", "no"].includes(value.toLowerCase()),
3353
+ parse: (value) => {
3354
+ const lower = value.toLowerCase();
3355
+ return ["true", "1", "yes"].includes(lower);
3356
+ }
3357
+ },
3358
+ {
3359
+ name: "number",
3360
+ canParse: (value, expectedType) => expectedType === "number" || !Number.isNaN(Number(value)) && !Number.isNaN(Number.parseFloat(value)),
3361
+ parse: (value) => {
3362
+ const num = Number(value);
3363
+ if (Number.isNaN(num)) {
3364
+ throw new TypeError(`Cannot parse "${value}" as number`);
3365
+ }
3366
+ return num;
3367
+ }
3368
+ },
3369
+ {
3370
+ name: "array",
3371
+ canParse: (value, expectedType) => expectedType === "array" || value.startsWith("[") || value.includes(","),
3372
+ parse: (value) => {
3373
+ try {
3374
+ const parsed = JSON.parse(value);
3375
+ if (Array.isArray(parsed)) {
3376
+ return parsed;
3377
+ }
3378
+ } catch {}
3379
+ return value.split(",").map((item) => item.trim());
3380
+ }
3381
+ },
3382
+ {
3383
+ name: "json",
3384
+ canParse: (value, expectedType) => expectedType === "object" || (value.startsWith("{") && value.endsWith("}") || value.startsWith("[") && value.endsWith("]")),
3385
+ parse: (value) => {
3386
+ try {
3387
+ return JSON.parse(value);
3388
+ } catch (error) {
3389
+ throw new Error(`Cannot parse "${value}" as JSON: ${error}`);
3390
+ }
3391
+ }
3392
+ }
3393
+ ];
3394
+ }
3395
+ async applyEnvironmentVariables(configName, config3, options = {}) {
3396
+ const {
3397
+ prefix,
3398
+ useCamelCase = true,
3399
+ useBackwardCompatibility = true,
3400
+ customParsers = {},
3401
+ verbose = false,
3402
+ trackPerformance = true
3403
+ } = options;
3404
+ const operation = async () => {
3405
+ if (!configName) {
3406
+ return {
3407
+ config: config3,
3408
+ source: { type: "environment", priority: 50, timestamp: new Date }
3409
+ };
3410
+ }
3411
+ const envPrefix = prefix || this.generateEnvPrefix(configName);
3412
+ const result = { ...config3 };
3413
+ this.processObject(result, [], envPrefix, {
3414
+ useCamelCase,
3415
+ useBackwardCompatibility,
3416
+ customParsers,
3417
+ verbose,
3418
+ configName
3419
+ });
3420
+ const source = {
3421
+ type: "environment",
3422
+ priority: 50,
3423
+ timestamp: new Date
3424
+ };
3425
+ return { config: result, source };
3426
+ };
3427
+ if (trackPerformance) {
3428
+ return globalPerformanceMonitor.track("applyEnvironmentVariables", operation, { configName });
3429
+ }
3430
+ return operation();
3431
+ }
3432
+ generateEnvPrefix(configName) {
3433
+ return configName.toUpperCase().replace(/-/g, "_");
3434
+ }
3435
+ formatEnvKey(key, useCamelCase) {
3436
+ if (!useCamelCase) {
3437
+ return key.toUpperCase();
3438
+ }
3439
+ return key.replace(/([A-Z])/g, "_$1").toUpperCase();
3440
+ }
3441
+ processObject(obj, path, envPrefix, options) {
3442
+ for (const [key, value] of Object.entries(obj)) {
3443
+ const envPath = [...path, key];
3444
+ const formattedKeys = envPath.map((k) => this.formatEnvKey(k, options.useCamelCase));
3445
+ const envKey = `${envPrefix}_${formattedKeys.join("_")}`;
3446
+ const oldEnvKey = options.useBackwardCompatibility ? `${envPrefix}_${envPath.map((p) => p.toUpperCase()).join("_")}` : null;
3447
+ if (options.verbose) {}
3448
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
3449
+ this.processObject(value, envPath, envPrefix, options);
3450
+ } else {
3451
+ const envValue = process8.env[envKey] || (oldEnvKey ? process8.env[oldEnvKey] : undefined);
3452
+ if (envValue !== undefined) {
3453
+ if (options.verbose) {
3454
+ const _usedKey = process8.env[envKey] ? envKey : oldEnvKey;
3455
+ }
3456
+ try {
3457
+ obj[key] = this.parseEnvironmentValue(envValue, typeof value, envKey, options.customParsers, options.configName);
3458
+ } catch (error) {
3459
+ if (error instanceof EnvVarError) {
3460
+ throw error;
3461
+ }
3462
+ throw ErrorFactory.envVar(envKey, envValue, typeof value, options.configName);
3463
+ }
3464
+ }
3465
+ }
3466
+ }
3467
+ }
3468
+ parseEnvironmentValue(envValue, expectedType, envKey, customParsers, configName) {
3469
+ for (const [_parserName, parser] of Object.entries(customParsers)) {
3470
+ try {
3471
+ return parser(envValue);
3472
+ } catch {
3473
+ continue;
3474
+ }
3475
+ }
3476
+ for (const parser of this.defaultParsers) {
3477
+ if (parser.canParse(envValue, expectedType)) {
3478
+ try {
3479
+ return parser.parse(envValue);
3480
+ } catch {
3481
+ throw ErrorFactory.envVar(envKey, envValue, `${expectedType} (via ${parser.name} parser)`, configName);
3482
+ }
3483
+ }
3484
+ }
3485
+ return envValue;
3486
+ }
3487
+ getEnvironmentVariables(prefix) {
3488
+ const envVars = {};
3489
+ const upperPrefix = prefix.toUpperCase();
3490
+ for (const [key, value] of Object.entries(process8.env)) {
3491
+ if (key.startsWith(upperPrefix) && value !== undefined) {
3492
+ envVars[key] = value;
3493
+ }
3494
+ }
3495
+ return envVars;
3496
+ }
3497
+ validateEnvironmentVariable(key, value, expectedType) {
3498
+ const errors = [];
3499
+ if (!/^[A-Z_][A-Z0-9_]*$/.test(key)) {
3500
+ errors.push(`Environment variable key "${key}" should only contain uppercase letters, numbers, and underscores`);
3501
+ }
3502
+ if (expectedType) {
3503
+ try {
3504
+ this.parseEnvironmentValue(key, value, expectedType, {});
3505
+ } catch (error) {
3506
+ errors.push(`Cannot parse value "${value}" as ${expectedType}: ${error}`);
3507
+ }
3508
+ }
3509
+ return {
3510
+ isValid: errors.length === 0,
3511
+ errors
3512
+ };
3513
+ }
3514
+ generateEnvVarDocs(configName, defaultConfig3, options = {}) {
3515
+ const { prefix, format = "text" } = options;
3516
+ const envPrefix = prefix || this.generateEnvPrefix(configName);
3517
+ const envVars = [];
3518
+ this.extractEnvVarInfo(defaultConfig3, [], envPrefix, envVars);
3519
+ switch (format) {
3520
+ case "markdown":
3521
+ return this.formatAsMarkdown(envVars, configName);
3522
+ case "json":
3523
+ return JSON.stringify(envVars, null, 2);
3524
+ default:
3525
+ return this.formatAsText(envVars, configName);
3526
+ }
3527
+ }
3528
+ extractEnvVarInfo(obj, path, prefix, envVars) {
3529
+ for (const [key, value] of Object.entries(obj)) {
3530
+ const envPath = [...path, key];
3531
+ const envKey = `${prefix}_${envPath.map((k) => this.formatEnvKey(k, true)).join("_")}`;
3532
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
3533
+ this.extractEnvVarInfo(value, envPath, prefix, envVars);
3534
+ } else {
3535
+ envVars.push({
3536
+ key: envKey,
3537
+ type: Array.isArray(value) ? "array" : typeof value,
3538
+ description: `Configuration for ${envPath.join(".")}`,
3539
+ example: this.generateExample(value)
3540
+ });
3541
+ }
3542
+ }
3543
+ }
3544
+ generateExample(value) {
3545
+ if (Array.isArray(value)) {
3546
+ return JSON.stringify(value);
3547
+ }
3548
+ if (typeof value === "object" && value !== null) {
3549
+ return JSON.stringify(value);
3550
+ }
3551
+ return String(value);
3552
+ }
3553
+ formatAsText(envVars, configName) {
3554
+ let result = `Environment Variables for ${configName}:
3555
+
3556
+ `;
3557
+ for (const envVar of envVars) {
3558
+ result += `${envVar.key}
3559
+ `;
3560
+ result += ` Type: ${envVar.type}
3561
+ `;
3562
+ result += ` Description: ${envVar.description}
3563
+ `;
3564
+ result += ` Example: ${envVar.example}
3565
+
3566
+ `;
3567
+ }
3568
+ return result;
3569
+ }
3570
+ formatAsMarkdown(envVars, configName) {
3571
+ let result = `# Environment Variables for ${configName}
3572
+
3573
+ `;
3574
+ result += `| Variable | Type | Description | Example |
3575
+ `;
3576
+ result += `|----------|------|-------------|----------|
3577
+ `;
3578
+ for (const envVar of envVars) {
3579
+ result += `| \`${envVar.key}\` | ${envVar.type} | ${envVar.description} | \`${envVar.example}\` |
3580
+ `;
3581
+ }
3582
+ return result;
3583
+ }
3584
+ }
3585
+ function deepMerge3(target, source, options = {}) {
3586
+ const visited = new WeakMap;
3587
+ return deepMergeWithVisited(target, source, options, visited);
3588
+ }
3589
+ function deepMergeWithVisited(target, source, options, visited) {
3590
+ const {
3591
+ arrayMergeMode = "replace",
3592
+ skipNullish = false,
3593
+ customMerger
3594
+ } = options;
3595
+ if (source === null || source === undefined) {
3596
+ return skipNullish ? target : source;
3597
+ }
3598
+ if (customMerger) {
3599
+ const customResult = customMerger(target, source);
3600
+ if (customResult !== undefined) {
3601
+ return customResult;
3602
+ }
3603
+ }
3604
+ if (Array.isArray(source) || Array.isArray(target)) {
3605
+ return mergeArraysWithVisited(target, source, arrayMergeMode, visited);
3606
+ }
3607
+ if (!isObject3(source) || !isObject3(target)) {
3608
+ return source;
3609
+ }
3610
+ return mergeObjectsWithVisited(target, source, options, visited);
3611
+ }
3612
+ function mergeArraysWithVisited(target, source, mode, visited) {
3613
+ if (Array.isArray(source) && !Array.isArray(target)) {
3614
+ return source;
3615
+ }
3616
+ if (Array.isArray(target) && !Array.isArray(source)) {
3617
+ return source;
3618
+ }
3619
+ if (Array.isArray(source) && Array.isArray(target)) {
3620
+ switch (mode) {
3621
+ case "replace":
3622
+ return source;
3623
+ case "concat":
3624
+ return concatArraysWithDedup(target, source);
3625
+ case "smart":
3626
+ return smartMergeArraysWithVisited(target, source, visited);
3627
+ default:
3628
+ return source;
3629
+ }
3630
+ }
3631
+ return source;
3632
+ }
3633
+ function concatArraysWithDedup(target, source) {
3634
+ const result = [...source];
3635
+ for (const item of target) {
3636
+ if (!result.some((existingItem) => deepEquals3(existingItem, item))) {
3637
+ result.push(item);
3638
+ }
3639
+ }
3640
+ return result;
3641
+ }
3642
+ function smartMergeArraysWithVisited(target, source, visited) {
3643
+ if (source.length === 0)
3644
+ return target;
3645
+ if (target.length === 0)
3646
+ return source;
3647
+ if (isObject3(source[0]) && isObject3(target[0])) {
3648
+ return mergeObjectArraysWithVisited(target, source, visited);
3649
+ }
3650
+ if (source.every((item) => typeof item === "string") && target.every((item) => typeof item === "string")) {
3651
+ const result = [...source];
3652
+ for (const item of target) {
3653
+ if (!result.includes(item)) {
3654
+ result.push(item);
3655
+ }
3656
+ }
3657
+ return result;
3658
+ }
3659
+ return source;
3660
+ }
3661
+ function mergeObjectArraysWithVisited(target, source, _visited) {
3662
+ const result = [...source];
3663
+ for (const targetItem of target) {
3664
+ if (!isObject3(targetItem)) {
3665
+ result.push(targetItem);
3666
+ continue;
3667
+ }
3668
+ const identifierKeys = ["id", "name", "key", "path", "type"];
3669
+ let hasMatch = false;
3670
+ for (const key of identifierKeys) {
3671
+ if (key in targetItem) {
3672
+ const existingItem = result.find((item) => isObject3(item) && (key in item) && item[key] === targetItem[key]);
3673
+ if (existingItem) {
3674
+ hasMatch = true;
3675
+ break;
3676
+ }
3677
+ }
3678
+ }
3679
+ if (!hasMatch) {
3680
+ result.push(targetItem);
3681
+ }
3682
+ }
3683
+ return result;
3684
+ }
3685
+ function mergeObjectsWithVisited(target, source, options, visited) {
3686
+ const sourceObj = source;
3687
+ if (isObject3(sourceObj) && visited.has(sourceObj)) {
3688
+ return visited.get(sourceObj);
3689
+ }
3690
+ const merged = { ...target };
3691
+ if (isObject3(sourceObj)) {
3692
+ visited.set(sourceObj, merged);
3693
+ }
3694
+ for (const key in sourceObj) {
3695
+ if (!Object.prototype.hasOwnProperty.call(sourceObj, key)) {
3696
+ continue;
3697
+ }
3698
+ const sourceValue = sourceObj[key];
3699
+ const targetValue = merged[key];
3700
+ if (options.skipNullish && (sourceValue === null || sourceValue === undefined)) {
3701
+ continue;
3702
+ }
3703
+ if (sourceValue === null || sourceValue === undefined) {
3704
+ merged[key] = sourceValue;
3705
+ continue;
3706
+ }
3707
+ if (isObject3(sourceValue) && isObject3(targetValue)) {
3708
+ merged[key] = deepMergeWithVisited(targetValue, sourceValue, options, visited);
3709
+ } else if (Array.isArray(sourceValue) || Array.isArray(targetValue)) {
3710
+ merged[key] = mergeArraysWithVisited(targetValue, sourceValue, options.arrayMergeMode || "smart", visited);
3711
+ } else {
3712
+ merged[key] = sourceValue;
3713
+ }
3714
+ }
3715
+ return merged;
3716
+ }
3717
+ function deepMergeWithArrayStrategy2(target, source, strategy = "replace") {
3718
+ const arrayMergeMode = strategy === "replace" ? "replace" : "smart";
3719
+ return deepMerge3(target, source, {
3720
+ arrayMergeMode,
3721
+ skipNullish: true
3722
+ });
3723
+ }
3724
+ function deepEquals3(a, b) {
3725
+ if (a === b)
3726
+ return true;
3727
+ if (Array.isArray(a) && Array.isArray(b)) {
3728
+ if (a.length !== b.length)
3729
+ return false;
3730
+ for (let i = 0;i < a.length; i++) {
3731
+ if (!deepEquals3(a[i], b[i]))
3732
+ return false;
3733
+ }
3734
+ return true;
3735
+ }
3736
+ if (isObject3(a) && isObject3(b)) {
3737
+ const keysA = Object.keys(a);
3738
+ const keysB = Object.keys(b);
3739
+ if (keysA.length !== keysB.length)
3740
+ return false;
3741
+ for (const key of keysA) {
3742
+ if (!Object.prototype.hasOwnProperty.call(b, key))
3743
+ return false;
3744
+ if (!deepEquals3(a[key], b[key]))
3745
+ return false;
3746
+ }
3747
+ return true;
3748
+ }
3749
+ return false;
3750
+ }
3751
+ function isObject3(item) {
3752
+ return Boolean(item && typeof item === "object" && !Array.isArray(item));
3753
+ }
3754
+
3755
+ class ConfigFileLoader {
3756
+ extensions = [".ts", ".js", ".mjs", ".cjs", ".json", ".mts", ".cts"];
3757
+ async loadFromPath(configPath, defaultConfig3, options = {}) {
3758
+ const {
3759
+ arrayStrategy = "replace",
3760
+ useCache = true,
3761
+ cacheTtl,
3762
+ trackPerformance = true,
3763
+ verbose = false
3764
+ } = options;
3765
+ if (useCache) {
3766
+ const cached = globalCache.getWithFileCheck("file", configPath);
3767
+ if (cached) {
3768
+ if (verbose) {
3769
+ console.log(`Configuration loaded from cache: ${configPath}`);
3770
+ }
3771
+ return cached;
3772
+ }
3773
+ }
3774
+ const loadOperation = async () => {
3775
+ if (!existsSync5(configPath)) {
3776
+ return null;
3777
+ }
3778
+ try {
3779
+ const cacheBuster = `?t=${Date.now()}`;
3780
+ const importedConfig = await import(configPath + cacheBuster);
3781
+ const loadedConfig = importedConfig.default || importedConfig;
3782
+ const hasDefaultExport = "default" in importedConfig;
3783
+ const hasNamedExports = Object.keys(importedConfig).length > 0;
3784
+ if (!hasDefaultExport && !hasNamedExports) {
3785
+ throw new ConfigLoadError(configPath, new Error("Configuration file is empty and exports nothing"), "unknown");
3786
+ }
3787
+ if (typeof loadedConfig !== "object" || loadedConfig === null || Array.isArray(loadedConfig)) {
3788
+ throw new ConfigLoadError(configPath, new Error("Configuration must export a valid object"), "unknown");
3789
+ }
3790
+ const mergedConfig = deepMergeWithArrayStrategy2(defaultConfig3, loadedConfig, arrayStrategy);
3791
+ const source = {
3792
+ type: "file",
3793
+ path: configPath,
3794
+ priority: 100,
3795
+ timestamp: new Date
3796
+ };
3797
+ const result = { config: mergedConfig, source };
3798
+ if (useCache) {
3799
+ globalCache.setWithFileCheck("file", result, configPath, cacheTtl);
3800
+ }
3801
+ return result;
3802
+ } catch (error) {
3803
+ const bunfigError = error instanceof Error ? ErrorFactory.configLoad(configPath, error) : ErrorFactory.configLoad(configPath, new Error(String(error)));
3804
+ throw bunfigError;
3805
+ }
3806
+ };
3807
+ if (trackPerformance) {
3808
+ return globalPerformanceMonitor.track("loadFromPath", loadOperation, { path: configPath });
3809
+ }
3810
+ return loadOperation();
3811
+ }
3812
+ async tryLoadFromPaths(configPaths, defaultConfig3, options = {}) {
3813
+ for (const configPath of configPaths) {
3814
+ try {
3815
+ const result = await this.loadFromPath(configPath, defaultConfig3, options);
3816
+ if (result) {
3817
+ return result;
3818
+ }
3819
+ } catch (error) {
3820
+ if (error instanceof Error && error.name === "ConfigLoadError") {
3821
+ throw error;
3822
+ }
3823
+ if (options.verbose) {
3824
+ console.warn(`Failed to load config from ${configPath}:`, error);
3825
+ }
3826
+ }
3827
+ }
3828
+ return null;
3829
+ }
3830
+ generateConfigPaths(configName, directory, alias) {
3831
+ const patterns = this.generateNamePatterns(configName, alias);
3832
+ const paths = [];
3833
+ for (const pattern of patterns) {
3834
+ for (const ext of this.extensions) {
3835
+ paths.push(resolve5(directory, `${pattern}${ext}`));
3836
+ }
3837
+ }
3838
+ return paths;
3839
+ }
3840
+ generateNamePatterns(configName, alias) {
3841
+ const patterns = [];
3842
+ patterns.push("config", ".config");
3843
+ if (configName) {
3844
+ patterns.push(configName, `.${configName}.config`, `${configName}.config`, `.${configName}`);
3845
+ }
3846
+ if (alias) {
3847
+ patterns.push(alias, `.${alias}.config`, `${alias}.config`, `.${alias}`);
3848
+ if (configName) {
3849
+ patterns.push(`${configName}.${alias}.config`, `.${configName}.${alias}.config`);
3850
+ }
3851
+ }
3852
+ return patterns.filter(Boolean);
3853
+ }
3854
+ checkFileAccess(filePath) {
3855
+ return withErrorRecovery(async () => {
3856
+ return existsSync5(filePath);
3857
+ }, {
3858
+ maxRetries: 2,
3859
+ retryDelay: 100,
3860
+ fallback: false
3861
+ });
3862
+ }
3863
+ async discoverConfigFiles(directory, configName, alias) {
3864
+ const discoveredFiles = [];
3865
+ if (!existsSync5(directory)) {
3866
+ return discoveredFiles;
3867
+ }
3868
+ if (configName || alias) {
3869
+ const patterns = this.generateNamePatterns(configName || "", alias);
3870
+ for (const pattern of patterns) {
3871
+ for (const ext of this.extensions) {
3872
+ const filePath = resolve5(directory, `${pattern}${ext}`);
3873
+ if (await this.checkFileAccess(filePath)) {
3874
+ discoveredFiles.push(filePath);
3875
+ }
3876
+ }
3877
+ }
3878
+ } else {
3879
+ try {
3880
+ const { readdirSync: readdirSync32 } = await import("fs");
3881
+ const files = readdirSync32(directory);
3882
+ for (const file of files) {
3883
+ if (this.looksLikeConfigFile(file)) {
3884
+ const filePath = resolve5(directory, file);
3885
+ if (await this.checkFileAccess(filePath)) {
3886
+ discoveredFiles.push(filePath);
3887
+ }
3888
+ }
3889
+ }
3890
+ } catch {
3891
+ return [];
3892
+ }
3893
+ }
3894
+ return discoveredFiles;
3895
+ }
3896
+ looksLikeConfigFile(filename) {
3897
+ const configPatterns = [
3898
+ /\.config\.(ts|js|mjs|cjs|json|mts|cts)$/,
3899
+ /^\..*\.(ts|js|mjs|cjs|json|mts|cts)$/,
3900
+ /config\.(ts|js|mjs|cjs|json|mts|cts)$/
3901
+ ];
3902
+ return configPatterns.some((pattern) => pattern.test(filename));
3903
+ }
3904
+ async validateConfigFile(filePath) {
3905
+ const errors = [];
3906
+ try {
3907
+ if (!existsSync5(filePath)) {
3908
+ errors.push("Configuration file does not exist");
3909
+ return errors;
3910
+ }
3911
+ const imported = await import(filePath);
3912
+ const config3 = imported.default || imported;
3913
+ if (config3 === undefined) {
3914
+ errors.push("Configuration file must export a default value or named exports");
3915
+ } else if (typeof config3 !== "object" || config3 === null) {
3916
+ errors.push("Configuration must be an object");
3917
+ } else if (Array.isArray(config3)) {
3918
+ errors.push("Configuration cannot be an array at the root level");
3919
+ }
3920
+ if (filePath.endsWith(".json")) {
3921
+ try {
3922
+ const { readFileSync } = await import("fs");
3923
+ const content = readFileSync(filePath, "utf8");
3924
+ JSON.parse(content);
3925
+ } catch (jsonError) {
3926
+ errors.push(`Invalid JSON syntax: ${jsonError}`);
3927
+ }
3928
+ }
3929
+ } catch (error) {
3930
+ errors.push(`Failed to load configuration file: ${error}`);
3931
+ }
3932
+ return errors;
3933
+ }
3934
+ async getFileModificationTime(filePath) {
3935
+ try {
3936
+ const { statSync: statSync2 } = await import("fs");
3937
+ const stats = statSync2(filePath);
3938
+ return stats.mtime;
3939
+ } catch {
3940
+ return null;
3941
+ }
3942
+ }
3943
+ async preloadConfigurations(configPaths, options = {}) {
3944
+ const preloaded = new Map;
3945
+ await Promise.allSettled(configPaths.map(async (path) => {
3946
+ try {
3947
+ const result = await this.loadFromPath(path, {}, options);
3948
+ if (result) {
3949
+ preloaded.set(path, result.config);
3950
+ }
3951
+ } catch (error) {
3952
+ if (options.verbose) {
3953
+ console.warn(`Failed to preload ${path}:`, error);
3954
+ }
3955
+ }
3956
+ }));
3957
+ return preloaded;
3958
+ }
3959
+ }
3960
+
3961
+ class ConfigValidator {
3962
+ async validateConfiguration(config3, schema, options = {}) {
3963
+ const {
3964
+ stopOnFirstError = false,
3965
+ validateRequired = true,
3966
+ validateTypes = true,
3967
+ customRules = [],
3968
+ trackPerformance = true,
3969
+ verbose = false
3970
+ } = options;
3971
+ const operation = async () => {
3972
+ const errors = [];
3973
+ const warnings = [];
3974
+ const resolvedOptions = {
3975
+ stopOnFirstError,
3976
+ validateRequired,
3977
+ validateTypes,
3978
+ customRules,
3979
+ trackPerformance,
3980
+ verbose
3981
+ };
3982
+ try {
3983
+ if (typeof schema === "string") {
3984
+ return await this.validateWithSchemaFile(config3, schema, resolvedOptions);
3985
+ } else if (Array.isArray(schema)) {
3986
+ return this.validateWithRules(config3, [...schema, ...customRules], resolvedOptions);
3987
+ } else {
3988
+ return this.validateWithJSONSchema(config3, schema, resolvedOptions);
3989
+ }
3990
+ } catch (error) {
3991
+ errors.push({
3992
+ path: "",
3993
+ message: `Validation failed: ${error}`,
3994
+ rule: "system"
3995
+ });
3996
+ return { isValid: false, errors, warnings };
3997
+ }
3998
+ };
3999
+ if (trackPerformance) {
4000
+ const result = await globalPerformanceMonitor.track("validateConfiguration", operation);
4001
+ return result;
4002
+ }
4003
+ return operation();
4004
+ }
4005
+ async validateWithSchemaFile(config3, schemaPath, options) {
4006
+ try {
4007
+ if (!existsSync7(schemaPath)) {
4008
+ throw new SchemaValidationError(schemaPath, [{ path: "", message: "Schema file does not exist" }]);
4009
+ }
4010
+ const schemaModule = await import(schemaPath);
4011
+ const schema = schemaModule.default || schemaModule;
4012
+ if (Array.isArray(schema)) {
4013
+ return this.validateWithRules(config3, schema, options);
4014
+ } else {
4015
+ return this.validateWithJSONSchema(config3, schema, options);
4016
+ }
4017
+ } catch (error) {
4018
+ throw new SchemaValidationError(schemaPath, [{ path: "", message: `Failed to load schema: ${error}` }]);
4019
+ }
4020
+ }
4021
+ validateWithJSONSchema(config3, schema, options) {
4022
+ const errors = [];
4023
+ const warnings = [];
4024
+ this.validateObjectAgainstSchema(config3, schema, "", errors, warnings, options);
4025
+ return {
4026
+ isValid: errors.length === 0,
4027
+ errors,
4028
+ warnings
4029
+ };
4030
+ }
4031
+ validateObjectAgainstSchema(value, schema, path, errors, warnings, options) {
4032
+ if (options.validateTypes && schema.type) {
4033
+ const actualType = Array.isArray(value) ? "array" : typeof value;
4034
+ const expectedTypes = Array.isArray(schema.type) ? schema.type : [schema.type];
4035
+ if (!expectedTypes.includes(actualType)) {
4036
+ errors.push({
4037
+ path,
4038
+ message: `Expected type ${expectedTypes.join(" or ")}, got ${actualType}`,
4039
+ expected: expectedTypes.join(" or "),
4040
+ actual: actualType,
4041
+ rule: "type"
4042
+ });
4043
+ if (options.stopOnFirstError)
4044
+ return;
4045
+ }
4046
+ }
4047
+ if (schema.enum && !schema.enum.includes(value)) {
4048
+ errors.push({
4049
+ path,
4050
+ message: `Value must be one of: ${schema.enum.join(", ")}`,
4051
+ expected: schema.enum.join(", "),
4052
+ actual: value,
4053
+ rule: "enum"
4054
+ });
4055
+ if (options.stopOnFirstError)
4056
+ return;
4057
+ }
4058
+ if (typeof value === "string") {
4059
+ if (schema.minLength !== undefined && value.length < schema.minLength) {
4060
+ errors.push({
4061
+ path,
4062
+ message: `String length must be at least ${schema.minLength}`,
4063
+ expected: `>= ${schema.minLength}`,
4064
+ actual: value.length,
4065
+ rule: "minLength"
4066
+ });
4067
+ }
4068
+ if (schema.maxLength !== undefined && value.length > schema.maxLength) {
4069
+ errors.push({
4070
+ path,
4071
+ message: `String length must not exceed ${schema.maxLength}`,
4072
+ expected: `<= ${schema.maxLength}`,
4073
+ actual: value.length,
4074
+ rule: "maxLength"
4075
+ });
4076
+ }
4077
+ if (schema.pattern) {
4078
+ const regex = new RegExp(schema.pattern);
4079
+ if (!regex.test(value)) {
4080
+ errors.push({
4081
+ path,
4082
+ message: `String does not match pattern ${schema.pattern}`,
4083
+ expected: schema.pattern,
4084
+ actual: value,
4085
+ rule: "pattern"
4086
+ });
4087
+ }
4088
+ }
4089
+ }
4090
+ if (typeof value === "number") {
4091
+ if (schema.minimum !== undefined && value < schema.minimum) {
4092
+ errors.push({
4093
+ path,
4094
+ message: `Value must be at least ${schema.minimum}`,
4095
+ expected: `>= ${schema.minimum}`,
4096
+ actual: value,
4097
+ rule: "minimum"
4098
+ });
4099
+ }
4100
+ if (schema.maximum !== undefined && value > schema.maximum) {
4101
+ errors.push({
4102
+ path,
4103
+ message: `Value must not exceed ${schema.maximum}`,
4104
+ expected: `<= ${schema.maximum}`,
4105
+ actual: value,
4106
+ rule: "maximum"
4107
+ });
4108
+ }
4109
+ }
4110
+ if (Array.isArray(value) && schema.items) {
4111
+ for (let i = 0;i < value.length; i++) {
4112
+ const itemPath = path ? `${path}[${i}]` : `[${i}]`;
4113
+ this.validateObjectAgainstSchema(value[i], schema.items, itemPath, errors, warnings, options);
4114
+ if (options.stopOnFirstError && errors.length > 0)
4115
+ return;
4116
+ }
4117
+ }
4118
+ if (value && typeof value === "object" && !Array.isArray(value)) {
4119
+ const obj = value;
4120
+ if (options.validateRequired && schema.required) {
4121
+ for (const requiredProp of schema.required) {
4122
+ if (!(requiredProp in obj)) {
4123
+ errors.push({
4124
+ path: path ? `${path}.${requiredProp}` : requiredProp,
4125
+ message: `Missing required property '${requiredProp}'`,
4126
+ expected: "required",
4127
+ rule: "required"
4128
+ });
4129
+ if (options.stopOnFirstError)
4130
+ return;
4131
+ }
4132
+ }
4133
+ }
4134
+ if (schema.properties) {
4135
+ for (const [propName, propSchema] of Object.entries(schema.properties)) {
4136
+ if (propName in obj) {
4137
+ const propPath = path ? `${path}.${propName}` : propName;
4138
+ this.validateObjectAgainstSchema(obj[propName], propSchema, propPath, errors, warnings, options);
4139
+ if (options.stopOnFirstError && errors.length > 0)
4140
+ return;
4141
+ }
4142
+ }
4143
+ }
4144
+ if (schema.additionalProperties === false) {
4145
+ const allowedProps = new Set(Object.keys(schema.properties || {}));
4146
+ for (const propName of Object.keys(obj)) {
4147
+ if (!allowedProps.has(propName)) {
4148
+ warnings.push({
4149
+ path: path ? `${path}.${propName}` : propName,
4150
+ message: `Additional property '${propName}' is not allowed`,
4151
+ rule: "additionalProperties"
4152
+ });
4153
+ }
4154
+ }
4155
+ }
4156
+ }
4157
+ }
4158
+ validateWithRules(config3, rules, options) {
4159
+ const errors = [];
4160
+ const warnings = [];
4161
+ for (const rule of rules) {
4162
+ try {
4163
+ const value = this.getValueByPath(config3, rule.path);
4164
+ const ruleErrors = this.validateWithRule(value, rule, rule.path);
4165
+ errors.push(...ruleErrors);
4166
+ if (options.stopOnFirstError && errors.length > 0) {
4167
+ break;
4168
+ }
4169
+ } catch (error) {
4170
+ errors.push({
4171
+ path: rule.path,
4172
+ message: `Rule validation failed: ${error}`,
4173
+ rule: "system"
4174
+ });
4175
+ }
4176
+ }
4177
+ return {
4178
+ isValid: errors.length === 0,
4179
+ errors,
4180
+ warnings
4181
+ };
4182
+ }
4183
+ validateWithRule(value, rule, path) {
4184
+ const errors = [];
4185
+ if (rule.required && (value === undefined || value === null)) {
4186
+ errors.push({
4187
+ path,
4188
+ message: rule.message || `Property '${path}' is required`,
4189
+ expected: "required",
4190
+ rule: "required"
4191
+ });
4192
+ return errors;
4193
+ }
4194
+ if (value === undefined || value === null) {
4195
+ return errors;
4196
+ }
4197
+ if (rule.type) {
4198
+ const actualType = Array.isArray(value) ? "array" : typeof value;
4199
+ if (actualType !== rule.type) {
4200
+ errors.push({
4201
+ path,
4202
+ message: rule.message || `Expected type ${rule.type}, got ${actualType}`,
4203
+ expected: rule.type,
4204
+ actual: actualType,
4205
+ rule: "type"
4206
+ });
4207
+ }
4208
+ }
4209
+ if (rule.min !== undefined) {
4210
+ const length = Array.isArray(value) ? value.length : typeof value === "string" ? value.length : typeof value === "number" ? value : 0;
4211
+ if (length < rule.min) {
4212
+ errors.push({
4213
+ path,
4214
+ message: rule.message || `Value must be at least ${rule.min}`,
4215
+ expected: `>= ${rule.min}`,
4216
+ actual: length,
4217
+ rule: "min"
4218
+ });
4219
+ }
4220
+ }
4221
+ if (rule.max !== undefined) {
4222
+ const length = Array.isArray(value) ? value.length : typeof value === "string" ? value.length : typeof value === "number" ? value : 0;
4223
+ if (length > rule.max) {
4224
+ errors.push({
4225
+ path,
4226
+ message: rule.message || `Value must not exceed ${rule.max}`,
4227
+ expected: `<= ${rule.max}`,
4228
+ actual: length,
4229
+ rule: "max"
4230
+ });
4231
+ }
4232
+ }
4233
+ if (rule.pattern && typeof value === "string") {
4234
+ if (!rule.pattern.test(value)) {
4235
+ errors.push({
4236
+ path,
4237
+ message: rule.message || `Value does not match pattern ${rule.pattern}`,
4238
+ expected: rule.pattern.toString(),
4239
+ actual: value,
4240
+ rule: "pattern"
4241
+ });
4242
+ }
4243
+ }
4244
+ if (rule.enum && !rule.enum.includes(value)) {
4245
+ errors.push({
4246
+ path,
4247
+ message: rule.message || `Value must be one of: ${rule.enum.join(", ")}`,
4248
+ expected: rule.enum.join(", "),
4249
+ actual: value,
4250
+ rule: "enum"
4251
+ });
4252
+ }
4253
+ if (rule.validator) {
4254
+ const customError = rule.validator(value);
4255
+ if (customError) {
4256
+ errors.push({
4257
+ path,
4258
+ message: rule.message || customError,
4259
+ rule: "custom"
4260
+ });
4261
+ }
4262
+ }
4263
+ return errors;
4264
+ }
4265
+ getValueByPath(obj, path) {
4266
+ if (!path)
4267
+ return obj;
4268
+ const keys = path.split(".");
4269
+ let current = obj;
4270
+ for (const key of keys) {
4271
+ if (current && typeof current === "object" && key in current) {
4272
+ current = current[key];
4273
+ } else {
4274
+ return;
4275
+ }
4276
+ }
4277
+ return current;
4278
+ }
4279
+ generateRulesFromInterface(interfaceCode) {
4280
+ const rules = [];
4281
+ const propertyMatches = interfaceCode.matchAll(/(\w+)(\?)?:\s*(\w+)/g);
4282
+ for (const match of propertyMatches) {
4283
+ const [, propName, optional, typeName] = match;
4284
+ rules.push({
4285
+ path: propName,
4286
+ required: !optional,
4287
+ type: this.mapTypeScriptType(typeName)
4288
+ });
4289
+ }
4290
+ return rules;
4291
+ }
4292
+ mapTypeScriptType(tsType) {
4293
+ switch (tsType.toLowerCase()) {
4294
+ case "string":
4295
+ return "string";
4296
+ case "number":
4297
+ return "number";
4298
+ case "boolean":
4299
+ return "boolean";
4300
+ case "array":
4301
+ return "array";
4302
+ case "object":
4303
+ return "object";
4304
+ default:
4305
+ return "object";
4306
+ }
4307
+ }
4308
+ static createCommonRules() {
4309
+ return {
4310
+ server: [
4311
+ { path: "port", required: true, type: "number", min: 1, max: 65535 },
4312
+ { path: "host", required: true, type: "string", min: 1 },
4313
+ { path: "ssl", type: "boolean" }
4314
+ ],
4315
+ database: [
4316
+ { path: "url", required: true, type: "string", min: 1 },
4317
+ { path: "pool", type: "number", min: 1, max: 100 },
4318
+ { path: "timeout", type: "number", min: 0 }
4319
+ ],
4320
+ api: [
4321
+ { path: "baseUrl", required: true, type: "string", pattern: URL_PATTERN },
4322
+ { path: "timeout", type: "number", min: 0 },
4323
+ { path: "retries", type: "number", min: 0, max: 10 }
4324
+ ]
4325
+ };
4326
+ }
4327
+ }
4328
+
4329
+ class ConfigLoader {
4330
+ fileLoader = new ConfigFileLoader;
4331
+ envProcessor = new EnvProcessor;
4332
+ validator = new ConfigValidator;
4333
+ async loadConfig(options) {
4334
+ const startTime = Date.now();
4335
+ const {
4336
+ cache,
4337
+ performance: performance2,
4338
+ schema,
4339
+ validate: customValidator,
4340
+ ...baseOptions
4341
+ } = options;
4342
+ try {
4343
+ if (cache?.enabled) {
4344
+ const cached = this.checkCache(baseOptions.name || "", baseOptions);
4345
+ if (cached) {
4346
+ return cached;
4347
+ }
4348
+ }
4349
+ let result;
4350
+ try {
4351
+ result = await this.loadConfigurationStrategies(baseOptions, true, cache);
4352
+ } catch (error) {
4353
+ const isStrictMode = baseOptions.__strictErrorHandling;
4354
+ if (error instanceof Error && error.name === "ConfigNotFoundError") {
4355
+ if (isStrictMode) {
4356
+ throw error;
4357
+ }
4358
+ const envResult = await this.applyEnvironmentVariables(baseOptions.name || "", baseOptions.defaultConfig, baseOptions.checkEnv !== false, baseOptions.verbose || false);
4359
+ result = {
4360
+ ...envResult,
4361
+ warnings: [`No configuration file found for "${baseOptions.name || "config"}", using defaults with environment variables`]
4362
+ };
4363
+ } else if (error instanceof Error && error.name === "ConfigLoadError") {
4364
+ const isPermissionError = error.message.includes("EACCES") || error.message.includes("EPERM") || error.message.includes("permission denied");
4365
+ const isSyntaxError = !isPermissionError && (error.message.includes("syntax") || error.message.includes("Expected") || error.message.includes("Unexpected") || error.message.includes("BuildMessage") || error.message.includes("errors building"));
4366
+ const isStructureError = error.message.includes("Configuration must export a valid object") || error.message.includes("Configuration file is empty and exports nothing");
4367
+ if (isStrictMode && (isStructureError || isPermissionError)) {
4368
+ throw error;
4369
+ }
4370
+ if (isSyntaxError && (!isStrictMode || !isStructureError)) {
4371
+ const envResult = await this.applyEnvironmentVariables(baseOptions.name || "", baseOptions.defaultConfig, baseOptions.checkEnv !== false, baseOptions.verbose || false);
4372
+ result = {
4373
+ ...envResult,
4374
+ warnings: [`Configuration file has syntax errors, using defaults with environment variables`]
4375
+ };
4376
+ } else if (!isStrictMode) {
4377
+ const envResult = await this.applyEnvironmentVariables(baseOptions.name || "", baseOptions.defaultConfig, baseOptions.checkEnv !== false, baseOptions.verbose || false);
4378
+ result = {
4379
+ ...envResult,
4380
+ warnings: [`Configuration loading error, using defaults: ${error.message}`]
4381
+ };
4382
+ } else {
4383
+ throw error;
4384
+ }
4385
+ } else {
4386
+ const envResult = await this.applyEnvironmentVariables(baseOptions.name || "", baseOptions.defaultConfig, baseOptions.checkEnv !== false, baseOptions.verbose || false);
4387
+ result = {
4388
+ ...envResult,
4389
+ warnings: [`Configuration loading failed, using defaults: ${error instanceof Error ? error.message : String(error)}`]
4390
+ };
4391
+ }
4392
+ }
4393
+ if (schema || customValidator) {
4394
+ await this.validateConfiguration(result.config, schema, customValidator, baseOptions.name);
4395
+ }
4396
+ if (cache?.enabled && result) {
4397
+ this.cacheResult(baseOptions.name || "", result, cache, baseOptions);
4398
+ }
4399
+ if (performance2?.enabled) {
4400
+ const metrics = {
4401
+ operation: "loadConfig",
4402
+ duration: Date.now() - startTime,
4403
+ configName: baseOptions.name,
4404
+ timestamp: new Date
4405
+ };
4406
+ if (performance2.onMetrics) {
4407
+ performance2.onMetrics(metrics);
4408
+ }
4409
+ if (performance2.slowThreshold && metrics.duration > performance2.slowThreshold) {
4410
+ log2.warn(`Slow configuration loading detected: ${metrics.duration}ms for ${baseOptions.name}`);
4411
+ }
4412
+ result.metrics = metrics;
4413
+ }
4414
+ return result;
4415
+ } catch (error) {
4416
+ const duration = Date.now() - startTime;
4417
+ log2.error(`Configuration loading failed after ${duration}ms:`, [error instanceof Error ? error : new Error(String(error))]);
4418
+ throw error;
4419
+ }
4420
+ }
4421
+ async loadConfigurationStrategies(options, throwOnNotFound = false, cacheOptions) {
4422
+ const {
4423
+ name = "",
4424
+ alias,
4425
+ cwd,
4426
+ configDir,
4427
+ defaultConfig: defaultConfig3,
4428
+ checkEnv = true,
4429
+ arrayStrategy = "replace",
4430
+ verbose = false
4431
+ } = options;
4432
+ const baseDir = cwd || process12.cwd();
4433
+ const searchPaths = [];
4434
+ const localResult = await this.loadLocalConfiguration(name, alias, baseDir, configDir, defaultConfig3, arrayStrategy, verbose, checkEnv, cacheOptions);
4435
+ if (localResult) {
4436
+ searchPaths.push(...this.getLocalSearchPaths(name, alias, baseDir, configDir));
4437
+ return this.finalizeResult(localResult, searchPaths, checkEnv, name, verbose);
4438
+ }
4439
+ const homeResult = await this.loadHomeConfiguration(name, alias, defaultConfig3, arrayStrategy, verbose, checkEnv);
4440
+ if (homeResult) {
4441
+ searchPaths.push(...this.getHomeSearchPaths(name, alias));
4442
+ return this.finalizeResult(homeResult, searchPaths, checkEnv, name, verbose);
4443
+ }
4444
+ const packageResult = await this.loadPackageJsonConfiguration(name, alias, baseDir, defaultConfig3, arrayStrategy, verbose, checkEnv);
4445
+ if (packageResult) {
4446
+ searchPaths.push(resolve7(baseDir, "package.json"));
4447
+ return this.finalizeResult(packageResult, searchPaths, checkEnv, name, verbose);
4448
+ }
4449
+ searchPaths.push(...this.getAllSearchPaths(name, alias, baseDir, configDir));
4450
+ if (throwOnNotFound) {
4451
+ throw ErrorFactory.configNotFound(name, searchPaths, alias);
4452
+ }
4453
+ const envResult = await this.applyEnvironmentVariables(name, defaultConfig3, checkEnv, verbose);
4454
+ return {
4455
+ ...envResult,
4456
+ warnings: [`No configuration file found for "${name}"${alias ? ` or alias "${alias}"` : ""}, using defaults with environment variables`]
4457
+ };
1713
4458
  }
1714
- if (name) {
1715
- const homeConfigDir = resolve3(homedir(), ".config");
1716
- const homeConfigDotfilePatterns = [`.${name}.config`];
1717
- if (alias)
1718
- homeConfigDotfilePatterns.push(`.${alias}.config`);
1719
- if (verbose)
1720
- log.info(`Checking user config directory for dotfile configs: ${homeConfigDir}`);
1721
- for (const configPath of homeConfigDotfilePatterns) {
1722
- for (const ext of extensions) {
1723
- const fullPath = resolve3(homeConfigDir, `${configPath}${ext}`);
1724
- const config3 = await tryLoadConfig2(fullPath, configWithEnvVars, arrayStrategy);
1725
- if (config3 !== null) {
1726
- if (verbose)
1727
- log.success(`Configuration loaded from user config directory dotfile: ${fullPath}`);
1728
- return config3;
4459
+ async loadLocalConfiguration(name, alias, baseDir, configDir, defaultConfig3, arrayStrategy, verbose, checkEnv, cacheOptions) {
4460
+ const envDefaultConfig = checkEnv ? applyEnvVarsToConfig2(name, defaultConfig3, verbose) : defaultConfig3;
4461
+ const searchDirectories = this.getLocalDirectories(baseDir, configDir);
4462
+ for (const directory of searchDirectories) {
4463
+ if (verbose) {
4464
+ log2.info(`Searching for configuration in: ${directory}`);
4465
+ }
4466
+ const configPaths = this.fileLoader.generateConfigPaths(name, directory, alias);
4467
+ const result = await this.fileLoader.tryLoadFromPaths(configPaths, envDefaultConfig, {
4468
+ arrayStrategy,
4469
+ verbose,
4470
+ cacheTtl: cacheOptions?.ttl,
4471
+ useCache: !cacheOptions?.ttl || cacheOptions.ttl > 100
4472
+ });
4473
+ if (result) {
4474
+ if (verbose) {
4475
+ log2.success(`Configuration loaded from: ${result.source.path}`);
1729
4476
  }
4477
+ return result;
1730
4478
  }
1731
4479
  }
4480
+ return null;
1732
4481
  }
1733
- if (name) {
1734
- const homeDir = homedir();
1735
- const homeRootPatterns = [`.${name}.config`, `.${name}`];
1736
- if (alias) {
1737
- homeRootPatterns.push(`.${alias}.config`);
1738
- homeRootPatterns.push(`.${alias}`);
1739
- }
1740
- if (verbose)
1741
- log.info(`Checking user home directory for dotfile configs: ${homeDir}`);
1742
- for (const configPath of homeRootPatterns) {
1743
- for (const ext of extensions) {
1744
- const fullPath = resolve3(homeDir, `${configPath}${ext}`);
1745
- const config3 = await tryLoadConfig2(fullPath, configWithEnvVars, arrayStrategy);
1746
- if (config3 !== null) {
1747
- if (verbose)
1748
- log.success(`Configuration loaded from user home directory: ${fullPath}`);
1749
- return config3;
4482
+ async loadHomeConfiguration(name, alias, defaultConfig3, arrayStrategy, verbose, checkEnv) {
4483
+ if (!name)
4484
+ return null;
4485
+ const envDefaultConfig = checkEnv ? applyEnvVarsToConfig2(name, defaultConfig3, verbose) : defaultConfig3;
4486
+ const homeDirectories = [
4487
+ resolve7(homedir2(), ".config", name),
4488
+ resolve7(homedir2(), ".config"),
4489
+ homedir2()
4490
+ ];
4491
+ for (const directory of homeDirectories) {
4492
+ if (verbose) {
4493
+ log2.info(`Checking home directory: ${directory}`);
4494
+ }
4495
+ const configPaths = this.fileLoader.generateConfigPaths(name, directory, alias);
4496
+ const result = await this.fileLoader.tryLoadFromPaths(configPaths, envDefaultConfig, { arrayStrategy, verbose });
4497
+ if (result) {
4498
+ if (verbose) {
4499
+ log2.success(`Configuration loaded from home directory: ${result.source.path}`);
1750
4500
  }
4501
+ return result;
1751
4502
  }
1752
4503
  }
4504
+ return null;
1753
4505
  }
1754
- try {
1755
- const pkgPath = resolve3(baseDir, "package.json");
1756
- if (existsSync3(pkgPath)) {
4506
+ async loadPackageJsonConfiguration(name, alias, baseDir, defaultConfig3, arrayStrategy, verbose, checkEnv) {
4507
+ const envDefaultConfig = checkEnv ? applyEnvVarsToConfig2(name, defaultConfig3, verbose) : defaultConfig3;
4508
+ try {
4509
+ const pkgPath = resolve7(baseDir, "package.json");
4510
+ if (!existsSync8(pkgPath)) {
4511
+ return null;
4512
+ }
1757
4513
  const pkg = await import(pkgPath);
1758
4514
  let pkgConfig = pkg[name];
4515
+ let usedName = name;
1759
4516
  if (!pkgConfig && alias) {
1760
4517
  pkgConfig = pkg[alias];
1761
- if (pkgConfig && verbose) {
1762
- log.success(`Using alias "${alias}" configuration from package.json`);
1763
- }
4518
+ usedName = alias;
1764
4519
  }
1765
4520
  if (pkgConfig && typeof pkgConfig === "object" && !Array.isArray(pkgConfig)) {
1766
- try {
1767
- if (verbose) {
1768
- log.success(`Configuration loaded from package.json: ${pkgConfig === pkg[name] ? name : alias}`);
1769
- }
1770
- return deepMergeWithArrayStrategy(configWithEnvVars, pkgConfig, arrayStrategy);
1771
- } catch (error) {
1772
- if (verbose) {
1773
- log.warn(`Failed to merge package.json config:`, error);
4521
+ if (verbose) {
4522
+ log2.success(`Configuration loaded from package.json: ${usedName}`);
4523
+ }
4524
+ const mergedConfig = deepMergeWithArrayStrategy2(envDefaultConfig, pkgConfig, arrayStrategy);
4525
+ return {
4526
+ config: mergedConfig,
4527
+ source: {
4528
+ type: "package.json",
4529
+ path: pkgPath,
4530
+ priority: 30,
4531
+ timestamp: new Date
1774
4532
  }
4533
+ };
4534
+ }
4535
+ } catch (error) {
4536
+ if (verbose) {
4537
+ log2.warn(`Failed to load package.json:`, [error instanceof Error ? error : new Error(String(error))]);
4538
+ }
4539
+ }
4540
+ return null;
4541
+ }
4542
+ async applyEnvironmentVariables(name, config3, checkEnv, verbose) {
4543
+ if (!checkEnv || !name || typeof config3 !== "object" || config3 === null || Array.isArray(config3)) {
4544
+ return {
4545
+ config: config3,
4546
+ source: {
4547
+ type: "default",
4548
+ priority: 10,
4549
+ timestamp: new Date
1775
4550
  }
4551
+ };
4552
+ }
4553
+ const processedConfig = applyEnvVarsToConfig2(name, config3, verbose);
4554
+ return {
4555
+ config: processedConfig,
4556
+ source: {
4557
+ type: "environment",
4558
+ priority: 20,
4559
+ timestamp: new Date
1776
4560
  }
4561
+ };
4562
+ }
4563
+ async finalizeResult(result, _searchPaths, _checkEnv, _name, _verbose) {
4564
+ return {
4565
+ config: result.config,
4566
+ source: result.source,
4567
+ path: result.source.path
4568
+ };
4569
+ }
4570
+ async validateConfiguration(config3, schema, customValidator, configName) {
4571
+ const errors = [];
4572
+ if (customValidator) {
4573
+ const customErrors = customValidator(config3);
4574
+ if (customErrors) {
4575
+ errors.push(...customErrors);
4576
+ }
4577
+ }
4578
+ if (schema) {
4579
+ const validationResult = await this.validator.validateConfiguration(config3, schema);
4580
+ if (!validationResult.isValid) {
4581
+ errors.push(...validationResult.errors.map((e) => e.path ? `${e.path}: ${e.message}` : e.message));
4582
+ }
4583
+ }
4584
+ if (errors.length > 0) {
4585
+ throw ErrorFactory.configValidation(configName || "unknown", errors, configName);
4586
+ }
4587
+ }
4588
+ checkCache(configName, options) {
4589
+ const cacheKey = this.generateCacheKey(configName, options);
4590
+ const result = globalCache.get(cacheKey);
4591
+ return result || null;
4592
+ }
4593
+ cacheResult(configName, result, cacheOptions, options) {
4594
+ const cacheKey = this.generateCacheKey(configName, options);
4595
+ globalCache.set(cacheKey, result, undefined, cacheOptions.ttl);
4596
+ }
4597
+ generateCacheKey(configName, options) {
4598
+ const keyParts = [configName];
4599
+ if (options.alias)
4600
+ keyParts.push(`alias:${options.alias}`);
4601
+ if (options.cwd)
4602
+ keyParts.push(`cwd:${options.cwd}`);
4603
+ if (options.configDir)
4604
+ keyParts.push(`configDir:${options.configDir}`);
4605
+ if ("checkEnv" in options)
4606
+ keyParts.push(`checkEnv:${options.checkEnv}`);
4607
+ return keyParts.join("|");
4608
+ }
4609
+ getLocalDirectories(baseDir, configDir) {
4610
+ return Array.from(new Set([
4611
+ baseDir,
4612
+ resolve7(baseDir, "config"),
4613
+ resolve7(baseDir, ".config"),
4614
+ configDir ? resolve7(baseDir, configDir) : undefined
4615
+ ].filter(Boolean)));
4616
+ }
4617
+ getAllSearchPaths(name, alias, baseDir, configDir) {
4618
+ const paths = [];
4619
+ paths.push(...this.getLocalSearchPaths(name, alias, baseDir, configDir));
4620
+ paths.push(...this.getHomeSearchPaths(name, alias));
4621
+ paths.push(resolve7(baseDir, "package.json"));
4622
+ return paths;
4623
+ }
4624
+ getLocalSearchPaths(name, alias, baseDir, configDir) {
4625
+ const directories = this.getLocalDirectories(baseDir, configDir);
4626
+ const paths = [];
4627
+ for (const directory of directories) {
4628
+ paths.push(...this.fileLoader.generateConfigPaths(name, directory, alias));
4629
+ }
4630
+ return paths;
4631
+ }
4632
+ getHomeSearchPaths(name, alias) {
4633
+ if (!name)
4634
+ return [];
4635
+ const homeDirectories = [
4636
+ resolve7(homedir2(), ".config", name),
4637
+ resolve7(homedir2(), ".config"),
4638
+ homedir2()
4639
+ ];
4640
+ const paths = [];
4641
+ for (const directory of homeDirectories) {
4642
+ paths.push(...this.fileLoader.generateConfigPaths(name, directory, alias));
4643
+ }
4644
+ return paths;
4645
+ }
4646
+ async loadConfigWithResult(options) {
4647
+ return this.loadConfig(options);
4648
+ }
4649
+ }
4650
+ async function loadConfig5(options) {
4651
+ const defaultConfig3 = "defaultConfig" in options && options.defaultConfig !== undefined ? options.defaultConfig : {};
4652
+ const isEnhanced = "cache" in options || "performance" in options || "schema" in options || "validate" in options;
4653
+ try {
4654
+ let result;
4655
+ if (isEnhanced) {
4656
+ result = await globalConfigLoader.loadConfig(options);
4657
+ } else {
4658
+ result = await globalConfigLoader.loadConfig({
4659
+ ...options,
4660
+ defaultConfig: defaultConfig3,
4661
+ cache: { enabled: true },
4662
+ performance: { enabled: false }
4663
+ });
1777
4664
  }
4665
+ return result?.config ?? defaultConfig3;
1778
4666
  } catch (error) {
1779
- if (verbose) {
1780
- log.warn(`Failed to load package.json:`, error);
4667
+ const errorName = error instanceof Error ? error.name : "UnknownError";
4668
+ const errorMessage = error instanceof Error ? error.message : String(error);
4669
+ const isConfigError = errorName === "ConfigNotFoundError" || errorName === "ConfigLoadError" || errorName === "ConfigValidationError" || errorMessage.includes("config");
4670
+ if (!isConfigError && options.verbose) {
4671
+ log2.warn(`Unexpected error loading config, using defaults:`, [error instanceof Error ? error : new Error(String(error))]);
4672
+ }
4673
+ const configOptions = isEnhanced ? { ...options, defaultConfig: defaultConfig3 } : {
4674
+ ...options,
4675
+ defaultConfig: defaultConfig3,
4676
+ cache: { enabled: true },
4677
+ performance: { enabled: false }
4678
+ };
4679
+ const shouldCheckEnv = "checkEnv" in options ? options.checkEnv !== false : true;
4680
+ if (shouldCheckEnv) {
4681
+ const envResult = await globalConfigLoader.applyEnvironmentVariables(configOptions.name || "", defaultConfig3, true, configOptions.verbose || false);
4682
+ return envResult?.config ?? defaultConfig3;
1781
4683
  }
4684
+ return defaultConfig3;
1782
4685
  }
1783
- if (verbose) {
1784
- log.info(`No configuration found for "${name}"${alias ? ` or alias "${alias}"` : ""}, using default configuration with environment variables`);
4686
+ }
4687
+ function applyEnvVarsToConfig2(name, config4, verbose = false) {
4688
+ const _envProcessor = new EnvProcessor;
4689
+ const envPrefix = name.toUpperCase().replace(/[^A-Z0-9]/g, "_");
4690
+ function processConfigLevel(obj, path = []) {
4691
+ const result = { ...obj };
4692
+ for (const [key, value] of Object.entries(obj)) {
4693
+ const currentPath = [...path, key];
4694
+ const envKeys = [
4695
+ `${envPrefix}_${currentPath.join("_").toUpperCase()}`,
4696
+ `${envPrefix}_${currentPath.map((k) => k.toUpperCase()).join("")}`,
4697
+ `${envPrefix}_${currentPath.map((k) => k.replace(/([A-Z])/g, "_$1").toUpperCase()).join("")}`
4698
+ ];
4699
+ let envValue;
4700
+ let usedKey;
4701
+ for (const envKey of envKeys) {
4702
+ envValue = process12.env[envKey];
4703
+ if (envValue !== undefined) {
4704
+ usedKey = envKey;
4705
+ break;
4706
+ }
4707
+ }
4708
+ if (envValue !== undefined && usedKey) {
4709
+ if (verbose) {}
4710
+ if (typeof value === "boolean") {
4711
+ result[key] = ["true", "1", "yes"].includes(envValue.toLowerCase());
4712
+ } else if (typeof value === "number") {
4713
+ const parsed = Number(envValue);
4714
+ if (!Number.isNaN(parsed)) {
4715
+ result[key] = parsed;
4716
+ }
4717
+ } else if (Array.isArray(value)) {
4718
+ try {
4719
+ result[key] = JSON.parse(envValue);
4720
+ } catch {
4721
+ result[key] = envValue.split(",").map((s) => s.trim());
4722
+ }
4723
+ } else {
4724
+ result[key] = envValue;
4725
+ }
4726
+ } else if (value && typeof value === "object" && !Array.isArray(value)) {
4727
+ result[key] = processConfigLevel(value, currentPath);
4728
+ }
4729
+ }
4730
+ return result;
1785
4731
  }
1786
- return configWithEnvVars;
4732
+ return processConfigLevel(config4);
1787
4733
  }
1788
- var defaultConfigDir, defaultGeneratedDir, defaultLogDirectory, defaultConfig, config, terminalStyles, styles, red, green, yellow, blue, magenta, cyan, white, gray, bgRed, bgYellow, bold, dim, italic, underline, reset, defaultFingersCrossedConfig, levelIcons, logger, log, defaultConfigDir2, defaultGeneratedDir2;
4734
+ var globalCache, globalPerformanceMonitor, defaultConfigDir, defaultGeneratedDir, defaultLogDirectory, defaultConfig, config, terminalStyles, styles, red, green, yellow, blue, magenta, cyan, white, gray, bgRed, bgYellow, bold, dim, italic, underline, reset, defaultFingersCrossedConfig, levelIcons, logger, log, defaultConfigDir2, defaultGeneratedDir2, defaultLogDirectory2, defaultConfig2, config2, terminalStyles2, styles2, red2, green2, yellow2, blue2, magenta2, cyan2, white2, gray2, bgRed2, bgYellow2, bgGray, bold2, dim2, italic2, underline2, strikethrough, reset2, defaultFingersCrossedConfig2, levelIcons2, logger2, BunfigError, ConfigNotFoundError, ConfigLoadError, ConfigValidationError, ConfigMergeError, EnvVarError, FileSystemError, TypeGenerationError, SchemaValidationError, BrowserConfigError, PluginError, ErrorFactory, URL_PATTERN, log2, globalConfigLoader, defaultConfigDir3, defaultGeneratedDir3;
1789
4735
  var init_dist = __esm(async () => {
4736
+ globalCache = new ConfigCache;
4737
+ globalPerformanceMonitor = new PerformanceMonitor;
1790
4738
  defaultConfigDir = resolve(process.cwd(), "config");
1791
4739
  defaultGeneratedDir = resolve(process.cwd(), "src/generated");
1792
4740
  defaultLogDirectory = process2.env.CLARITY_LOG_DIR || join(getProjectRoot(), "logs");
@@ -1865,13 +4813,272 @@ var init_dist = __esm(async () => {
1865
4813
  });
1866
4814
  defaultConfigDir2 = resolve3(process6.cwd(), "config");
1867
4815
  defaultGeneratedDir2 = resolve3(process6.cwd(), "src/generated");
4816
+ defaultLogDirectory2 = process7.env.CLARITY_LOG_DIR || join3(getProjectRoot2(), "logs");
4817
+ defaultConfig2 = {
4818
+ level: "info",
4819
+ defaultName: "clarity",
4820
+ timestamp: true,
4821
+ colors: true,
4822
+ format: "text",
4823
+ maxLogSize: 10485760,
4824
+ logDatePattern: "YYYY-MM-DD",
4825
+ logDirectory: defaultLogDirectory2,
4826
+ rotation: {
4827
+ frequency: "daily",
4828
+ maxSize: 10485760,
4829
+ maxFiles: 5,
4830
+ compress: false,
4831
+ rotateHour: 0,
4832
+ rotateMinute: 0,
4833
+ rotateDayOfWeek: 0,
4834
+ rotateDayOfMonth: 1,
4835
+ encrypt: false
4836
+ },
4837
+ verbose: false,
4838
+ writeToFile: false
4839
+ };
4840
+ config2 = await loadConfig4();
4841
+ terminalStyles2 = {
4842
+ red: (text) => `\x1B[31m${text}\x1B[0m`,
4843
+ green: (text) => `\x1B[32m${text}\x1B[0m`,
4844
+ yellow: (text) => `\x1B[33m${text}\x1B[0m`,
4845
+ blue: (text) => `\x1B[34m${text}\x1B[0m`,
4846
+ magenta: (text) => `\x1B[35m${text}\x1B[0m`,
4847
+ cyan: (text) => `\x1B[36m${text}\x1B[0m`,
4848
+ white: (text) => `\x1B[37m${text}\x1B[0m`,
4849
+ gray: (text) => `\x1B[90m${text}\x1B[0m`,
4850
+ bgRed: (text) => `\x1B[41m${text}\x1B[0m`,
4851
+ bgYellow: (text) => `\x1B[43m${text}\x1B[0m`,
4852
+ bgGray: (text) => `\x1B[100m${text}\x1B[0m`,
4853
+ bold: (text) => `\x1B[1m${text}\x1B[0m`,
4854
+ dim: (text) => `\x1B[2m${text}\x1B[0m`,
4855
+ italic: (text) => `\x1B[3m${text}\x1B[0m`,
4856
+ underline: (text) => `\x1B[4m${text}\x1B[0m`,
4857
+ strikethrough: (text) => `\x1B[9m${text}\x1B[0m`,
4858
+ reset: "\x1B[0m"
4859
+ };
4860
+ styles2 = terminalStyles2;
4861
+ red2 = terminalStyles2.red;
4862
+ green2 = terminalStyles2.green;
4863
+ yellow2 = terminalStyles2.yellow;
4864
+ blue2 = terminalStyles2.blue;
4865
+ magenta2 = terminalStyles2.magenta;
4866
+ cyan2 = terminalStyles2.cyan;
4867
+ white2 = terminalStyles2.white;
4868
+ gray2 = terminalStyles2.gray;
4869
+ bgRed2 = terminalStyles2.bgRed;
4870
+ bgYellow2 = terminalStyles2.bgYellow;
4871
+ bgGray = terminalStyles2.bgGray;
4872
+ bold2 = terminalStyles2.bold;
4873
+ dim2 = terminalStyles2.dim;
4874
+ italic2 = terminalStyles2.italic;
4875
+ underline2 = terminalStyles2.underline;
4876
+ strikethrough = terminalStyles2.strikethrough;
4877
+ reset2 = terminalStyles2.reset;
4878
+ defaultFingersCrossedConfig2 = {
4879
+ activationLevel: "error",
4880
+ bufferSize: 50,
4881
+ flushOnDeactivation: true,
4882
+ stopBuffering: false
4883
+ };
4884
+ levelIcons2 = {
4885
+ debug: "\uD83D\uDD0D",
4886
+ info: blue2("\u2139"),
4887
+ success: green2("\u2713"),
4888
+ warning: bgYellow2(white2(bold2(" WARN "))),
4889
+ error: bgRed2(white2(bold2(" ERROR ")))
4890
+ };
4891
+ logger2 = new Logger2("stacks");
4892
+ BunfigError = class BunfigError extends Error {
4893
+ timestamp;
4894
+ context;
4895
+ constructor(message, context = {}) {
4896
+ super(message);
4897
+ this.name = this.constructor.name;
4898
+ this.timestamp = new Date;
4899
+ this.context = context;
4900
+ if (Error.captureStackTrace) {
4901
+ Error.captureStackTrace(this, this.constructor);
4902
+ }
4903
+ }
4904
+ toJSON() {
4905
+ return {
4906
+ name: this.name,
4907
+ code: this.code,
4908
+ message: this.message,
4909
+ timestamp: this.timestamp.toISOString(),
4910
+ context: this.context,
4911
+ stack: this.stack
4912
+ };
4913
+ }
4914
+ toString() {
4915
+ const contextStr = Object.keys(this.context).length > 0 ? ` (${Object.entries(this.context).map(([k, v]) => `${k}: ${v}`).join(", ")})` : "";
4916
+ return `${this.name} [${this.code}]: ${this.message}${contextStr}`;
4917
+ }
4918
+ };
4919
+ ConfigNotFoundError = class ConfigNotFoundError extends BunfigError {
4920
+ code = "CONFIG_NOT_FOUND";
4921
+ constructor(configName, searchPaths, alias) {
4922
+ const aliasStr = alias ? ` or alias "${alias}"` : "";
4923
+ super(`Configuration "${configName}"${aliasStr} not found`, {
4924
+ configName,
4925
+ alias,
4926
+ searchPaths,
4927
+ searchPathCount: searchPaths.length
4928
+ });
4929
+ }
4930
+ };
4931
+ ConfigLoadError = class ConfigLoadError extends BunfigError {
4932
+ code = "CONFIG_LOAD_ERROR";
4933
+ constructor(configPath, cause, configName) {
4934
+ super(`Failed to load configuration from "${configPath}": ${cause.message}`, {
4935
+ configPath,
4936
+ configName,
4937
+ originalError: cause.name,
4938
+ originalMessage: cause.message
4939
+ });
4940
+ this.cause = cause;
4941
+ }
4942
+ };
4943
+ ConfigValidationError = class ConfigValidationError extends BunfigError {
4944
+ code = "CONFIG_VALIDATION_ERROR";
4945
+ constructor(configPath, validationErrors, configName) {
4946
+ super(`Configuration validation failed for "${configPath}"`, {
4947
+ configPath,
4948
+ configName,
4949
+ validationErrors,
4950
+ errorCount: validationErrors.length
4951
+ });
4952
+ }
4953
+ };
4954
+ ConfigMergeError = class ConfigMergeError extends BunfigError {
4955
+ code = "CONFIG_MERGE_ERROR";
4956
+ constructor(sourcePath, targetPath, cause, configName) {
4957
+ super(`Failed to merge configuration from "${sourcePath}" with "${targetPath}": ${cause.message}`, {
4958
+ sourcePath,
4959
+ targetPath,
4960
+ configName,
4961
+ originalError: cause.name,
4962
+ originalMessage: cause.message
4963
+ });
4964
+ this.cause = cause;
4965
+ }
4966
+ };
4967
+ EnvVarError = class EnvVarError extends BunfigError {
4968
+ code = "ENV_VAR_ERROR";
4969
+ constructor(envKey, envValue, expectedType, configName) {
4970
+ super(`Failed to parse environment variable "${envKey}" with value "${envValue}" as ${expectedType}`, {
4971
+ envKey,
4972
+ envValue,
4973
+ expectedType,
4974
+ configName
4975
+ });
4976
+ }
4977
+ };
4978
+ FileSystemError = class FileSystemError extends BunfigError {
4979
+ code = "FILE_SYSTEM_ERROR";
4980
+ constructor(operation, path, cause) {
4981
+ super(`File system ${operation} failed for "${path}": ${cause.message}`, {
4982
+ operation,
4983
+ path,
4984
+ originalError: cause.name,
4985
+ originalMessage: cause.message
4986
+ });
4987
+ this.cause = cause;
4988
+ }
4989
+ };
4990
+ TypeGenerationError = class TypeGenerationError extends BunfigError {
4991
+ code = "TYPE_GENERATION_ERROR";
4992
+ constructor(configDir, outputPath, cause) {
4993
+ super(`Failed to generate types from "${configDir}" to "${outputPath}": ${cause.message}`, {
4994
+ configDir,
4995
+ outputPath,
4996
+ originalError: cause.name,
4997
+ originalMessage: cause.message
4998
+ });
4999
+ this.cause = cause;
5000
+ }
5001
+ };
5002
+ SchemaValidationError = class SchemaValidationError extends BunfigError {
5003
+ code = "SCHEMA_VALIDATION_ERROR";
5004
+ constructor(schemaPath, validationErrors, configName) {
5005
+ super(`Schema validation failed${configName ? ` for config "${configName}"` : ""}`, {
5006
+ schemaPath,
5007
+ configName,
5008
+ validationErrors,
5009
+ errorCount: validationErrors.length
5010
+ });
5011
+ }
5012
+ };
5013
+ BrowserConfigError = class BrowserConfigError extends BunfigError {
5014
+ code = "BROWSER_CONFIG_ERROR";
5015
+ constructor(endpoint, status, statusText, configName) {
5016
+ super(`Failed to fetch configuration from "${endpoint}": ${status} ${statusText}`, {
5017
+ endpoint,
5018
+ status,
5019
+ statusText,
5020
+ configName
5021
+ });
5022
+ }
5023
+ };
5024
+ PluginError = class PluginError extends BunfigError {
5025
+ code = "PLUGIN_ERROR";
5026
+ constructor(pluginName, operation, cause) {
5027
+ super(`Plugin "${pluginName}" failed during ${operation}: ${cause.message}`, {
5028
+ pluginName,
5029
+ operation,
5030
+ originalError: cause.name,
5031
+ originalMessage: cause.message
5032
+ });
5033
+ this.cause = cause;
5034
+ }
5035
+ };
5036
+ ErrorFactory = {
5037
+ configNotFound(configName, searchPaths, alias) {
5038
+ return new ConfigNotFoundError(configName, searchPaths, alias);
5039
+ },
5040
+ configLoad(configPath, cause, configName) {
5041
+ return new ConfigLoadError(configPath, cause, configName);
5042
+ },
5043
+ configValidation(configPath, errors, configName) {
5044
+ return new ConfigValidationError(configPath, errors, configName);
5045
+ },
5046
+ configMerge(sourcePath, targetPath, cause, configName) {
5047
+ return new ConfigMergeError(sourcePath, targetPath, cause, configName);
5048
+ },
5049
+ envVar(envKey, envValue, expectedType, configName) {
5050
+ return new EnvVarError(envKey, envValue, expectedType, configName);
5051
+ },
5052
+ fileSystem(operation, path, cause) {
5053
+ return new FileSystemError(operation, path, cause);
5054
+ },
5055
+ typeGeneration(configDir, outputPath, cause) {
5056
+ return new TypeGenerationError(configDir, outputPath, cause);
5057
+ },
5058
+ schemaValidation(schemaPath, errors, configName) {
5059
+ return new SchemaValidationError(schemaPath, errors, configName);
5060
+ },
5061
+ browserConfig(endpoint, status, statusText, configName) {
5062
+ return new BrowserConfigError(endpoint, status, statusText, configName);
5063
+ },
5064
+ plugin(pluginName, operation, cause) {
5065
+ return new PluginError(pluginName, operation, cause);
5066
+ }
5067
+ };
5068
+ URL_PATTERN = /^https?:\/\//;
5069
+ log2 = new Logger2("bunfig", {
5070
+ showTags: true
5071
+ });
5072
+ globalConfigLoader = new ConfigLoader;
5073
+ defaultConfigDir3 = resolve7(process12.cwd(), "config");
5074
+ defaultGeneratedDir3 = resolve7(process12.cwd(), "src/generated");
1868
5075
  });
1869
5076
 
1870
5077
  // src/config.ts
1871
- var defaultConfig2, config2;
5078
+ var defaultConfig3, config3;
1872
5079
  var init_config = __esm(async () => {
1873
5080
  await init_dist();
1874
- defaultConfig2 = {
5081
+ defaultConfig3 = {
1875
5082
  verbose: true,
1876
5083
  dialect: "postgres",
1877
5084
  database: {
@@ -1928,16 +5135,16 @@ var init_config = __esm(async () => {
1928
5135
  defaultFilter: true
1929
5136
  }
1930
5137
  };
1931
- config2 = await loadConfig3({
5138
+ config3 = await loadConfig5({
1932
5139
  name: "query-builder",
1933
5140
  alias: "qb",
1934
- defaultConfig: defaultConfig2
5141
+ defaultConfig: defaultConfig3
1935
5142
  });
1936
5143
  });
1937
5144
 
1938
5145
  // src/db.ts
1939
5146
  var {SQL } = globalThis.Bun;
1940
- import process7 from "process";
5147
+ import process13 from "process";
1941
5148
  function createConnectionString(dialect, dbConfig) {
1942
5149
  if (dbConfig.url) {
1943
5150
  return dbConfig.url;
@@ -1958,12 +5165,12 @@ function createConnectionString(dialect, dbConfig) {
1958
5165
  }
1959
5166
  }
1960
5167
  function getBunSql() {
1961
- const connectionString = createConnectionString(config2.dialect, config2.database);
5168
+ const connectionString = createConnectionString(config3.dialect, config3.database);
1962
5169
  try {
1963
5170
  const sql = new SQL(connectionString);
1964
5171
  if (sql && typeof sql.catch === "function") {
1965
5172
  sql.catch((error) => {
1966
- if (config2.verbose && !error.message.includes("database") && !error.message.includes("does not exist")) {
5173
+ if (config3.verbose && !error.message.includes("database") && !error.message.includes("does not exist")) {
1967
5174
  console.warn(`[query-builder] Database connection error: ${error.message}`);
1968
5175
  }
1969
5176
  });
@@ -2007,14 +5214,14 @@ var _bunSqlInstance = null, bunSql;
2007
5214
  var init_db = __esm(async () => {
2008
5215
  await init_config();
2009
5216
  bunSql = getOrCreateBunSql();
2010
- if (typeof process7 !== "undefined" && process7.on) {
2011
- const existingHandler = process7.listeners("unhandledRejection").find((h) => h.name === "sqlConnectionErrorHandler");
5217
+ if (typeof process13 !== "undefined" && process13.on) {
5218
+ const existingHandler = process13.listeners("unhandledRejection").find((h) => h.name === "sqlConnectionErrorHandler");
2012
5219
  if (!existingHandler) {
2013
5220
  let sqlConnectionErrorHandler = function(reason) {
2014
5221
  if (reason && (reason.message?.includes("database") || reason.message?.includes("does not exist") || reason.code === "ERR_POSTGRES_SERVER_ERROR" || reason.code === "3D000")) {}
2015
5222
  };
2016
5223
  Object.defineProperty(sqlConnectionErrorHandler, "name", { value: "sqlConnectionErrorHandler" });
2017
- process7.on("unhandledRejection", sqlConnectionErrorHandler);
5224
+ process13.on("unhandledRejection", sqlConnectionErrorHandler);
2018
5225
  }
2019
5226
  }
2020
5227
  });
@@ -2233,7 +5440,7 @@ function matchesSqlState(err, states) {
2233
5440
  return states.includes(code);
2234
5441
  }
2235
5442
  function sleep(ms) {
2236
- return new Promise((resolve4) => setTimeout(resolve4, ms));
5443
+ return new Promise((resolve8) => setTimeout(resolve8, ms));
2237
5444
  }
2238
5445
  function computeBackoffMs(attempt, cfg) {
2239
5446
  const base = Math.max(1, cfg?.baseMs ?? 50);
@@ -2313,16 +5520,16 @@ function createQueryBuilder(state) {
2313
5520
  return _sql`${q} WHERE ${condition}`;
2314
5521
  }
2315
5522
  function computeSqlText(q) {
2316
- const prev = config2.debug?.captureText;
2317
- if (config2.debug)
2318
- config2.debug.captureText = true;
5523
+ const prev = config3.debug?.captureText;
5524
+ if (config3.debug)
5525
+ config3.debug.captureText = true;
2319
5526
  const s = String(q);
2320
- if (config2.debug)
2321
- config2.debug.captureText = prev;
5527
+ if (config3.debug)
5528
+ config3.debug.captureText = prev;
2322
5529
  return s;
2323
5530
  }
2324
5531
  function runWithHooks(q, kind, opts) {
2325
- const hooks = config2.hooks;
5532
+ const hooks = config3.hooks;
2326
5533
  const hasHooks = hooks && (hooks.onQueryStart || hooks.onQueryEnd || hooks.onQueryError || hooks.startSpan);
2327
5534
  const hasTimeoutOrSignal = opts?.timeoutMs && opts.timeoutMs > 0 || opts?.signal;
2328
5535
  if (!hasHooks && !hasTimeoutOrSignal) {
@@ -2671,7 +5878,7 @@ function createQueryBuilder(state) {
2671
5878
  }
2672
5879
  if (normalizedRelations.length === 0)
2673
5880
  return this;
2674
- const maxEagerLoad = config2.relations.maxEagerLoad ?? 50;
5881
+ const maxEagerLoad = config3.relations.maxEagerLoad ?? 50;
2675
5882
  if (normalizedRelations.length > maxEagerLoad) {
2676
5883
  throw new Error(`[query-builder] Too many relationships to eager load (${normalizedRelations.length}). Maximum allowed: ${maxEagerLoad}`);
2677
5884
  }
@@ -2680,7 +5887,7 @@ function createQueryBuilder(state) {
2680
5887
  const loadedRelationships = new Set;
2681
5888
  const relationConditions = new Map;
2682
5889
  const singularize = (name) => {
2683
- if (config2.relations.singularizeStrategy === "none")
5890
+ if (config3.relations.singularizeStrategy === "none")
2684
5891
  return name;
2685
5892
  return name.endsWith("s") ? name.slice(0, -1) : name;
2686
5893
  };
@@ -2702,7 +5909,7 @@ function createQueryBuilder(state) {
2702
5909
  ];
2703
5910
  };
2704
5911
  const addJoin = (fromTable, relationKey, depth = 0, condition) => {
2705
- const maxDepth = config2.relations.maxDepth ?? 10;
5912
+ const maxDepth = config3.relations.maxDepth ?? 10;
2706
5913
  if (depth >= maxDepth) {
2707
5914
  throw new Error(`[query-builder] Maximum relationship depth (${maxDepth}) exceeded at '${relationKey}'. Consider using separate queries or increasing maxDepth.`);
2708
5915
  }
@@ -2712,8 +5919,8 @@ function createQueryBuilder(state) {
2712
5919
  }
2713
5920
  const _buildConditionalJoin = (baseJoinCondition, targetTable2) => {
2714
5921
  let joinCondition = baseJoinCondition;
2715
- if (config2.softDeletes?.enabled && config2.softDeletes?.defaultFilter) {
2716
- const softDeleteColumn = config2.softDeletes.column || "deleted_at";
5922
+ if (config3.softDeletes?.enabled && config3.softDeletes?.defaultFilter) {
5923
+ const softDeleteColumn = config3.softDeletes.column || "deleted_at";
2717
5924
  joinCondition = `${joinCondition} AND ${targetTable2}.${softDeleteColumn} IS NULL`;
2718
5925
  }
2719
5926
  if (!condition)
@@ -2733,8 +5940,8 @@ function createQueryBuilder(state) {
2733
5940
  return joinCondition;
2734
5941
  };
2735
5942
  const addSoftDeleteCheck = (table2) => {
2736
- if (config2.softDeletes?.enabled && config2.softDeletes?.defaultFilter) {
2737
- const softDeleteColumn = config2.softDeletes.column || "deleted_at";
5943
+ if (config3.softDeletes?.enabled && config3.softDeletes?.defaultFilter) {
5944
+ const softDeleteColumn = config3.softDeletes.column || "deleted_at";
2738
5945
  return ` AND ${table2}.${softDeleteColumn} IS NULL`;
2739
5946
  }
2740
5947
  return "";
@@ -2759,7 +5966,7 @@ function createQueryBuilder(state) {
2759
5966
  throw new Error(`[query-builder] Relationship '${relationKey}' not found on table '${fromTable}'.${suggestion}`);
2760
5967
  }
2761
5968
  }
2762
- if (config2.relations.detectCycles !== false) {
5969
+ if (config3.relations.detectCycles !== false) {
2763
5970
  const cycleKey = `${fromTable}->${childTable}`;
2764
5971
  if (visitedTables.has(cycleKey)) {
2765
5972
  throw new Error(`[query-builder] Circular relationship detected: ${cycleKey}. This would cause an infinite loop.`);
@@ -3168,7 +6375,7 @@ function createQueryBuilder(state) {
3168
6375
  return this;
3169
6376
  },
3170
6377
  whereJsonPath(path, op, value) {
3171
- const dialect = config2.dialect;
6378
+ const dialect = config3.dialect;
3172
6379
  if (dialect === "postgres") {
3173
6380
  built = sql`${built} WHERE ${sql(path)} ${op} ${value}`;
3174
6381
  } else if (dialect === "mysql") {
@@ -3185,7 +6392,7 @@ function createQueryBuilder(state) {
3185
6392
  return this;
3186
6393
  },
3187
6394
  whereILike(column, pattern) {
3188
- if (config2.dialect === "postgres") {
6395
+ if (config3.dialect === "postgres") {
3189
6396
  built = sql`${built} WHERE ${sql(String(column))} ILIKE ${pattern}`;
3190
6397
  addWhereText("WHERE", `${String(column)} ILIKE ?`);
3191
6398
  } else {
@@ -3202,7 +6409,7 @@ function createQueryBuilder(state) {
3202
6409
  return this;
3203
6410
  },
3204
6411
  orWhereILike(column, pattern) {
3205
- if (config2.dialect === "postgres") {
6412
+ if (config3.dialect === "postgres") {
3206
6413
  built = sql`${built} OR ${sql(String(column))} ILIKE ${pattern}`;
3207
6414
  addWhereText("OR", `${String(column)} ILIKE ?`);
3208
6415
  } else {
@@ -3219,7 +6426,7 @@ function createQueryBuilder(state) {
3219
6426
  return this;
3220
6427
  },
3221
6428
  whereNotILike(column, pattern) {
3222
- if (config2.dialect === "postgres") {
6429
+ if (config3.dialect === "postgres") {
3223
6430
  built = sql`${built} WHERE ${sql(String(column))} NOT ILIKE ${pattern}`;
3224
6431
  addWhereText("WHERE", `${String(column)} NOT ILIKE ?`);
3225
6432
  } else {
@@ -3236,7 +6443,7 @@ function createQueryBuilder(state) {
3236
6443
  return this;
3237
6444
  },
3238
6445
  orWhereNotILike(column, pattern) {
3239
- if (config2.dialect === "postgres") {
6446
+ if (config3.dialect === "postgres") {
3240
6447
  built = sql`${built} OR ${sql(String(column))} NOT ILIKE ${pattern}`;
3241
6448
  addWhereText("OR", `${String(column)} NOT ILIKE ?`);
3242
6449
  } else {
@@ -3448,7 +6655,7 @@ function createQueryBuilder(state) {
3448
6655
  return this;
3449
6656
  },
3450
6657
  inRandomOrder() {
3451
- const rnd = config2.sql.randomFunction === "RAND()" ? sql`RAND()` : sql`RANDOM()`;
6658
+ const rnd = config3.sql.randomFunction === "RAND()" ? sql`RAND()` : sql`RANDOM()`;
3452
6659
  built = sql`${built} ORDER BY ${rnd}`;
3453
6660
  return this;
3454
6661
  },
@@ -3457,12 +6664,12 @@ function createQueryBuilder(state) {
3457
6664
  return this;
3458
6665
  },
3459
6666
  latest(column) {
3460
- const col = column ?? config2.timestamps.defaultOrderColumn;
6667
+ const col = column ?? config3.timestamps.defaultOrderColumn;
3461
6668
  built = sql`${built} ORDER BY ${sql(String(col))} DESC`;
3462
6669
  return this;
3463
6670
  },
3464
6671
  oldest(column) {
3465
- const col = column ?? config2.timestamps.defaultOrderColumn;
6672
+ const col = column ?? config3.timestamps.defaultOrderColumn;
3466
6673
  built = sql`${built} ORDER BY ${sql(String(col))} ASC`;
3467
6674
  return this;
3468
6675
  },
@@ -3529,7 +6736,7 @@ function createQueryBuilder(state) {
3529
6736
  for (const jt of joinedTables) {
3530
6737
  const cols = Object.keys(schema[jt]?.columns ?? {});
3531
6738
  for (const c of cols) {
3532
- const alias = config2.aliasing.relationColumnAliasFormat === "camelCase" ? `${jt}_${c}`.replace(/_([a-z])/g, (_, ch) => ch.toUpperCase()) : config2.aliasing.relationColumnAliasFormat === "table.dot.column" ? `${jt}.${c}` : `${jt}_${c}`;
6739
+ const alias = config3.aliasing.relationColumnAliasFormat === "camelCase" ? `${jt}_${c}`.replace(/_([a-z])/g, (_, ch) => ch.toUpperCase()) : config3.aliasing.relationColumnAliasFormat === "table.dot.column" ? `${jt}.${c}` : `${jt}_${c}`;
3533
6740
  parts.push(sql`${sql(`${jt}.${c}`)} AS ${sql(alias)}`);
3534
6741
  }
3535
6742
  }
@@ -3717,7 +6924,7 @@ function createQueryBuilder(state) {
3717
6924
  onlyTrashed() {
3718
6925
  includeTrashed = true;
3719
6926
  onlyTrashed = true;
3720
- const softDeleteColumn = config2.softDeletes?.column || "deleted_at";
6927
+ const softDeleteColumn = config3.softDeletes?.column || "deleted_at";
3721
6928
  if (text.includes("WHERE")) {
3722
6929
  text = text.replace(/WHERE/, `WHERE ${table}.${softDeleteColumn} IS NOT NULL AND`);
3723
6930
  } else {
@@ -3777,7 +6984,7 @@ function createQueryBuilder(state) {
3777
6984
  },
3778
6985
  async get() {
3779
6986
  built = whereParams.length > 0 ? _sql.unsafe(text, whereParams) : _sql.unsafe(text);
3780
- if (!config2.softDeletes?.enabled && !useCache && !timeoutMs && !abortSignal && !config2.hooks) {
6987
+ if (!config3.softDeletes?.enabled && !useCache && !timeoutMs && !abortSignal && !config3.hooks) {
3781
6988
  const stmt = built._stmt;
3782
6989
  const params = built._params;
3783
6990
  if (stmt) {
@@ -3785,12 +6992,12 @@ function createQueryBuilder(state) {
3785
6992
  }
3786
6993
  return built.execute();
3787
6994
  }
3788
- if (!config2.softDeletes?.enabled && !useCache && !timeoutMs && !abortSignal) {
6995
+ if (!config3.softDeletes?.enabled && !useCache && !timeoutMs && !abortSignal) {
3789
6996
  return runWithHooks(built, "select");
3790
6997
  }
3791
6998
  let finalQuery = built;
3792
- if (config2.softDeletes?.enabled && config2.softDeletes.defaultFilter && !includeTrashed) {
3793
- const col = config2.softDeletes.column;
6999
+ if (config3.softDeletes?.enabled && config3.softDeletes.defaultFilter && !includeTrashed) {
7000
+ const col = config3.softDeletes.column;
3794
7001
  const tbl = String(table);
3795
7002
  const hasCol = schema ? Boolean(schema[tbl]?.columns?.[col]) : true;
3796
7003
  if (hasCol && !SQL_PATTERNS.DELETED_AT.test(text)) {
@@ -3921,7 +7128,7 @@ function createQueryBuilder(state) {
3921
7128
  return this;
3922
7129
  },
3923
7130
  sharedLock() {
3924
- const syntax = config2.sql.sharedLockSyntax === "LOCK IN SHARE MODE" ? sql`LOCK IN SHARE MODE` : sql`FOR SHARE`;
7131
+ const syntax = config3.sql.sharedLockSyntax === "LOCK IN SHARE MODE" ? sql`LOCK IN SHARE MODE` : sql`FOR SHARE`;
3925
7132
  built = sql`${built} ${syntax}`;
3926
7133
  return this;
3927
7134
  },
@@ -3989,7 +7196,7 @@ function createQueryBuilder(state) {
3989
7196
  }
3990
7197
  return {
3991
7198
  configure(opts) {
3992
- Object.assign(config2, opts);
7199
+ Object.assign(config3, opts);
3993
7200
  return this;
3994
7201
  },
3995
7202
  id(name) {
@@ -4417,13 +7624,13 @@ function createQueryBuilder(state) {
4417
7624
  },
4418
7625
  async execute() {
4419
7626
  try {
4420
- await config2.hooks?.beforeDelete?.({ table: String(table), where: whereCondition });
7627
+ await config3.hooks?.beforeDelete?.({ table: String(table), where: whereCondition });
4421
7628
  } catch (err) {
4422
7629
  throw err;
4423
7630
  }
4424
7631
  const result = await runWithHooks(built, "delete");
4425
7632
  try {
4426
- await config2.hooks?.afterDelete?.({ table: String(table), where: whereCondition, result });
7633
+ await config3.hooks?.afterDelete?.({ table: String(table), where: whereCondition, result });
4427
7634
  } catch {}
4428
7635
  return result;
4429
7636
  }
@@ -4457,7 +7664,7 @@ function createQueryBuilder(state) {
4457
7664
  return _sql(strings, ...values).simple();
4458
7665
  },
4459
7666
  async advisoryLock(key) {
4460
- if (config2.dialect !== "postgres")
7667
+ if (config3.dialect !== "postgres")
4461
7668
  return;
4462
7669
  const s = String(key);
4463
7670
  let hash = 7;
@@ -4468,7 +7675,7 @@ function createQueryBuilder(state) {
4468
7675
  await runWithHooks(q, "raw");
4469
7676
  },
4470
7677
  async tryAdvisoryLock(key) {
4471
- if (config2.dialect !== "postgres")
7678
+ if (config3.dialect !== "postgres")
4472
7679
  return false;
4473
7680
  const s = String(key);
4474
7681
  let hash = 7;
@@ -4520,7 +7727,7 @@ function createQueryBuilder(state) {
4520
7727
  for (let i = 0;i < attempts; i++) {
4521
7728
  if (await this.ping())
4522
7729
  return;
4523
- await new Promise((resolve4) => setTimeout(resolve4, delay));
7730
+ await new Promise((resolve8) => setTimeout(resolve8, delay));
4524
7731
  }
4525
7732
  throw new Error("Database not ready after waiting");
4526
7733
  },
@@ -4610,7 +7817,7 @@ function createQueryBuilder(state) {
4610
7817
  return built.execute();
4611
7818
  },
4612
7819
  async insertGetId(table, values, idColumn = "id") {
4613
- if (config2.dialect === "mysql") {
7820
+ if (config3.dialect === "mysql") {
4614
7821
  const insertQuery = bunSql`INSERT INTO ${bunSql(String(table))} ${bunSql(values)}`;
4615
7822
  const result = await insertQuery.execute();
4616
7823
  if (result && typeof result === "object" && "insertId" in result) {
@@ -4685,23 +7892,23 @@ function createQueryBuilder(state) {
4685
7892
  async rawQuery(query) {
4686
7893
  const start = Date.now();
4687
7894
  try {
4688
- config2.hooks?.onQueryStart?.({ sql: query, kind: "raw" });
7895
+ config3.hooks?.onQueryStart?.({ sql: query, kind: "raw" });
4689
7896
  const res = await bunSql.unsafe(query);
4690
- config2.hooks?.onQueryEnd?.({ sql: query, durationMs: Date.now() - start, kind: "raw" });
7897
+ config3.hooks?.onQueryEnd?.({ sql: query, durationMs: Date.now() - start, kind: "raw" });
4691
7898
  return res;
4692
7899
  } catch (err) {
4693
- config2.hooks?.onQueryError?.({ sql: query, error: err, durationMs: Date.now() - start, kind: "raw" });
7900
+ config3.hooks?.onQueryError?.({ sql: query, error: err, durationMs: Date.now() - start, kind: "raw" });
4694
7901
  throw err;
4695
7902
  }
4696
7903
  },
4697
7904
  async create(table, values) {
4698
7905
  const pk = meta?.primaryKeys[String(table)] ?? "id";
4699
7906
  try {
4700
- await config2.hooks?.beforeCreate?.({ table: String(table), data: values });
7907
+ await config3.hooks?.beforeCreate?.({ table: String(table), data: values });
4701
7908
  } catch (err) {
4702
7909
  throw err;
4703
7910
  }
4704
- if (config2.dialect === "postgres") {
7911
+ if (config3.dialect === "postgres") {
4705
7912
  const q = bunSql`INSERT INTO ${bunSql(String(table))} ${bunSql(values)} RETURNING ${bunSql(String(pk))} as id`;
4706
7913
  const [result] = await q.execute();
4707
7914
  console.log("resultId", result);
@@ -4717,7 +7924,7 @@ function createQueryBuilder(state) {
4717
7924
  throw new Error(`create() failed to retrieve inserted row for table ${String(table)} with id ${result.id}`);
4718
7925
  }
4719
7926
  try {
4720
- await config2.hooks?.afterCreate?.({ table: String(table), data: values, result: row });
7927
+ await config3.hooks?.afterCreate?.({ table: String(table), data: values, result: row });
4721
7928
  } catch {}
4722
7929
  return row;
4723
7930
  } else {
@@ -4732,7 +7939,7 @@ function createQueryBuilder(state) {
4732
7939
  throw new Error(`create() failed to retrieve inserted row for table ${String(table)} with id ${id}`);
4733
7940
  }
4734
7941
  try {
4735
- await config2.hooks?.afterCreate?.({ table: String(table), data: values, result: row });
7942
+ await config3.hooks?.afterCreate?.({ table: String(table), data: values, result: row });
4736
7943
  } catch {}
4737
7944
  return row;
4738
7945
  }
@@ -4995,7 +8202,7 @@ var init_cache = __esm(async () => {
4995
8202
  });
4996
8203
 
4997
8204
  // src/actions/console.ts
4998
- import process9 from "process";
8205
+ import process15 from "process";
4999
8206
  import { createInterface } from "readline";
5000
8207
  async function startConsole() {
5001
8208
  console.log("-- Query Builder Interactive Console");
@@ -5004,8 +8211,8 @@ async function startConsole() {
5004
8211
  console.log();
5005
8212
  const qb = createQueryBuilder();
5006
8213
  const rl = createInterface({
5007
- input: process9.stdin,
5008
- output: process9.stdout,
8214
+ input: process15.stdin,
8215
+ output: process15.stdout,
5009
8216
  prompt: "qb> "
5010
8217
  });
5011
8218
  let multilineBuffer = "";
@@ -5056,7 +8263,7 @@ Tips:
5056
8263
  if (cmd === ".exit" || cmd === ".quit") {
5057
8264
  console.log("Goodbye!");
5058
8265
  rl.close();
5059
- process9.exit(0);
8266
+ process15.exit(0);
5060
8267
  } else if (cmd === ".help") {
5061
8268
  console.log(helpText);
5062
8269
  } else if (cmd === ".clear") {
@@ -5127,7 +8334,7 @@ Tips:
5127
8334
  rl.on("close", () => {
5128
8335
  console.log(`
5129
8336
  Goodbye!`);
5130
- process9.exit(0);
8337
+ process15.exit(0);
5131
8338
  });
5132
8339
  rl.prompt();
5133
8340
  }
@@ -5139,7 +8346,7 @@ var init_console = __esm(async () => {
5139
8346
  });
5140
8347
 
5141
8348
  // src/actions/data.ts
5142
- import { existsSync as existsSync4, readFileSync, writeFileSync as writeFileSync4 } from "fs";
8349
+ import { existsSync as existsSync6, readFileSync, writeFileSync as writeFileSync6 } from "fs";
5143
8350
  async function exportData(tableName, options = {}) {
5144
8351
  const format = options.format || "json";
5145
8352
  const output = options.output || `${tableName}.${format}`;
@@ -5160,11 +8367,11 @@ async function exportData(tableName, options = {}) {
5160
8367
  const data = await query.execute();
5161
8368
  console.log(`-- Retrieved ${data.length} rows`);
5162
8369
  if (format === "json") {
5163
- writeFileSync4(output, JSON.stringify(data, null, 2));
8370
+ writeFileSync6(output, JSON.stringify(data, null, 2));
5164
8371
  console.log(`-- \u2713 Exported to JSON: ${output}`);
5165
8372
  } else if (format === "csv") {
5166
8373
  if (data.length === 0) {
5167
- writeFileSync4(output, "");
8374
+ writeFileSync6(output, "");
5168
8375
  console.log(`-- \u2713 Exported to CSV: ${output} (empty)`);
5169
8376
  return;
5170
8377
  }
@@ -5185,7 +8392,7 @@ async function exportData(tableName, options = {}) {
5185
8392
  });
5186
8393
  csvLines.push(values.join(","));
5187
8394
  }
5188
- writeFileSync4(output, csvLines.join(`
8395
+ writeFileSync6(output, csvLines.join(`
5189
8396
  `));
5190
8397
  console.log(`-- \u2713 Exported to CSV: ${output}`);
5191
8398
  } else if (format === "sql") {
@@ -5204,7 +8411,7 @@ async function exportData(tableName, options = {}) {
5204
8411
  });
5205
8412
  sqlLines.push(`INSERT INTO ${tableName} (${columns.join(", ")}) VALUES (${values.join(", ")});`);
5206
8413
  }
5207
- writeFileSync4(output, sqlLines.join(`
8414
+ writeFileSync6(output, sqlLines.join(`
5208
8415
  `));
5209
8416
  console.log(`-- \u2713 Exported to SQL: ${output}`);
5210
8417
  }
@@ -5214,7 +8421,7 @@ async function exportData(tableName, options = {}) {
5214
8421
  }
5215
8422
  }
5216
8423
  async function importData(tableName, filePath, options = {}) {
5217
- if (!existsSync4(filePath)) {
8424
+ if (!existsSync6(filePath)) {
5218
8425
  console.error(`-- File not found: ${filePath}`);
5219
8426
  throw new Error(`File not found: ${filePath}`);
5220
8427
  }
@@ -5283,7 +8490,7 @@ async function importData(tableName, filePath, options = {}) {
5283
8490
  }
5284
8491
  }
5285
8492
  async function dumpDatabase(options = {}) {
5286
- const dialect = config2.dialect || "postgres";
8493
+ const dialect = config3.dialect || "postgres";
5287
8494
  const output = options.output || `dump-${Date.now()}.sql`;
5288
8495
  const tablesToDump = options.tables?.split(",").map((t) => t.trim());
5289
8496
  console.log("-- Dumping database");
@@ -5358,7 +8565,7 @@ async function dumpDatabase(options = {}) {
5358
8565
  }
5359
8566
  sqlLines.push("");
5360
8567
  }
5361
- writeFileSync4(output, sqlLines.join(`
8568
+ writeFileSync6(output, sqlLines.join(`
5362
8569
  `));
5363
8570
  console.log();
5364
8571
  console.log(`-- \u2713 Database dump saved to: ${output}`);
@@ -5376,8 +8583,8 @@ var init_data = __esm(async () => {
5376
8583
 
5377
8584
  // src/actions/db-info.ts
5378
8585
  async function dbInfo() {
5379
- const dialect = config2.dialect || "postgres";
5380
- const database = config2.database?.database || "unknown";
8586
+ const dialect = config3.dialect || "postgres";
8587
+ const database = config3.database?.database || "unknown";
5381
8588
  console.log("-- Database Information");
5382
8589
  console.log(`-- Dialect: ${dialect}`);
5383
8590
  console.log(`-- Database: ${database}`);
@@ -5508,9 +8715,9 @@ var init_db_info = __esm(async () => {
5508
8715
  });
5509
8716
 
5510
8717
  // src/actions/db-optimize.ts
5511
- import process10 from "process";
8718
+ import process16 from "process";
5512
8719
  async function dbOptimize(options = {}) {
5513
- const dialect = options.dialect || process10.env.DB_DIALECT || "postgres";
8720
+ const dialect = options.dialect || process16.env.DB_DIALECT || "postgres";
5514
8721
  const aggressive = options.aggressive || false;
5515
8722
  if (options.verbose) {
5516
8723
  console.log(`Optimizing ${dialect} database${aggressive ? " (aggressive mode)" : ""}...`);
@@ -5550,7 +8757,7 @@ async function dbOptimize(options = {}) {
5550
8757
  await bunSql`ANALYZE TABLE ${bunSql(table)}`;
5551
8758
  }
5552
8759
  } else {
5553
- const dbName = process10.env.DB_NAME || "test";
8760
+ const dbName = process16.env.DB_NAME || "test";
5554
8761
  const tables = await bunSql`
5555
8762
  SELECT table_name
5556
8763
  FROM information_schema.tables
@@ -5602,9 +8809,9 @@ var init_db_optimize = __esm(async () => {
5602
8809
  });
5603
8810
 
5604
8811
  // src/actions/db-wipe.ts
5605
- import process11 from "process";
8812
+ import process17 from "process";
5606
8813
  async function dbWipe(options = {}) {
5607
- const dialect = options.dialect || process11.env.DB_DIALECT || "postgres";
8814
+ const dialect = options.dialect || process17.env.DB_DIALECT || "postgres";
5608
8815
  if (options.verbose) {
5609
8816
  console.log(`Wiping all tables from ${dialect} database...`);
5610
8817
  }
@@ -5618,7 +8825,7 @@ async function dbWipe(options = {}) {
5618
8825
  `;
5619
8826
  tables = result.map((row) => row.tablename);
5620
8827
  } else if (dialect === "mysql") {
5621
- const dbName = process11.env.DB_NAME || "test";
8828
+ const dbName = process17.env.DB_NAME || "test";
5622
8829
  const result = await bunSql`
5623
8830
  SELECT table_name
5624
8831
  FROM information_schema.tables
@@ -5703,7 +8910,7 @@ var init_file = __esm(async () => {
5703
8910
 
5704
8911
  // src/actions/inspect.ts
5705
8912
  async function inspectTable(tableName, options = {}) {
5706
- const dialect = config2.dialect || "postgres";
8913
+ const dialect = config3.dialect || "postgres";
5707
8914
  const verbose = options.verbose ?? true;
5708
8915
  if (verbose) {
5709
8916
  console.log(`-- Inspecting table: ${tableName}`);
@@ -5912,31 +9119,31 @@ var init_introspect = __esm(async () => {
5912
9119
  });
5913
9120
 
5914
9121
  // src/actions/make-model.ts
5915
- import { existsSync as existsSync6, mkdirSync as mkdirSync3, writeFileSync as writeFileSync6 } from "fs";
5916
- import { dirname as dirname3, join as join3 } from "path";
5917
- import process12 from "process";
9122
+ import { existsSync as existsSync9, mkdirSync as mkdirSync4, writeFileSync as writeFileSync8 } from "fs";
9123
+ import { dirname as dirname4, join as join4 } from "path";
9124
+ import process18 from "process";
5918
9125
  function findWorkspaceRoot(startPath) {
5919
9126
  let currentPath = startPath;
5920
- while (currentPath !== dirname3(currentPath)) {
5921
- if (existsSync6(join3(currentPath, "package.json"))) {
9127
+ while (currentPath !== dirname4(currentPath)) {
9128
+ if (existsSync9(join4(currentPath, "package.json"))) {
5922
9129
  return currentPath;
5923
9130
  }
5924
- currentPath = dirname3(currentPath);
9131
+ currentPath = dirname4(currentPath);
5925
9132
  }
5926
- return process12.cwd();
9133
+ return process18.cwd();
5927
9134
  }
5928
9135
  async function makeModel(name, options = {}) {
5929
- const workspaceRoot = findWorkspaceRoot(process12.cwd());
5930
- const modelsDir = options.dir || join3(workspaceRoot, "app/Models");
5931
- if (!existsSync6(modelsDir)) {
5932
- mkdirSync3(modelsDir, { recursive: true });
9136
+ const workspaceRoot = findWorkspaceRoot(process18.cwd());
9137
+ const modelsDir = options.dir || join4(workspaceRoot, "app/Models");
9138
+ if (!existsSync9(modelsDir)) {
9139
+ mkdirSync4(modelsDir, { recursive: true });
5933
9140
  console.log(`-- Created models directory: ${modelsDir}`);
5934
9141
  }
5935
9142
  const className = name.charAt(0).toUpperCase() + name.slice(1);
5936
9143
  const tableName = options.table || `${name.toLowerCase()}s`;
5937
9144
  const fileName = `${className}.ts`;
5938
- const filePath = join3(modelsDir, fileName);
5939
- if (existsSync6(filePath)) {
9145
+ const filePath = join4(modelsDir, fileName);
9146
+ if (existsSync9(filePath)) {
5940
9147
  console.error(`-- Model already exists: ${filePath}`);
5941
9148
  throw new Error(`Model already exists: ${filePath}`);
5942
9149
  }
@@ -5963,7 +9170,7 @@ ${timestampFields}
5963
9170
 
5964
9171
  export default model
5965
9172
  `;
5966
- writeFileSync6(filePath, template);
9173
+ writeFileSync8(filePath, template);
5967
9174
  console.log(`-- \u2713 Created model: ${filePath}`);
5968
9175
  console.log(`-- Table: ${tableName}`);
5969
9176
  }
@@ -6441,42 +9648,42 @@ __export(exports_migrate, {
6441
9648
  deleteMigrationFiles: () => deleteMigrationFiles,
6442
9649
  copyModelsToGenerated: () => copyModelsToGenerated
6443
9650
  });
6444
- import { copyFileSync, existsSync as existsSync7, mkdirSync as mkdirSync5, mkdtempSync, readdirSync as readdirSync3, readFileSync as readFileSync2, unlinkSync, writeFileSync as writeFileSync7 } from "fs";
9651
+ import { copyFileSync, existsSync as existsSync11, mkdirSync as mkdirSync6, mkdtempSync, readdirSync as readdirSync4, readFileSync as readFileSync2, unlinkSync, writeFileSync as writeFileSync9 } from "fs";
6445
9652
  import { tmpdir } from "os";
6446
- import { join as join5 } from "path";
6447
- import process13 from "process";
9653
+ import { join as join6 } from "path";
9654
+ import process19 from "process";
6448
9655
  function getWorkspaceRoot() {
6449
- return process13.cwd();
9656
+ return process19.cwd();
6450
9657
  }
6451
9658
  function ensureSqlDirectory(workspaceRoot) {
6452
9659
  const sqlDir = getSqlDirectory(workspaceRoot);
6453
- if (!existsSync7(sqlDir)) {
6454
- mkdirSync5(sqlDir, { recursive: true });
9660
+ if (!existsSync11(sqlDir)) {
9661
+ mkdirSync6(sqlDir, { recursive: true });
6455
9662
  console.log(`-- Created SQL directory: ${sqlDir}`);
6456
9663
  }
6457
9664
  return sqlDir;
6458
9665
  }
6459
9666
  async function generateMigration(dir, opts = {}) {
6460
9667
  if (!dir) {
6461
- dir = join5(process13.cwd(), "app/Models");
9668
+ dir = join6(process19.cwd(), "app/Models");
6462
9669
  }
6463
- const dialect = opts.dialect || config2.dialect || "postgres";
9670
+ const dialect = opts.dialect || config3.dialect || "postgres";
6464
9671
  const workspaceRoot = getWorkspaceRoot();
6465
9672
  const models = await loadModels({ modelsDir: dir });
6466
9673
  const plan = buildMigrationPlan(models, { dialect });
6467
- const defaultStatePath = join5(dir, `.qb-migrations.${dialect}.json`);
9674
+ const defaultStatePath = join6(dir, `.qb-migrations.${dialect}.json`);
6468
9675
  const statePath = String(opts.state || defaultStatePath);
6469
9676
  let previous;
6470
9677
  if (!opts.full) {
6471
- const generatedDir = join5(workspaceRoot, "generated");
6472
- if (existsSync7(generatedDir)) {
9678
+ const generatedDir = join6(workspaceRoot, "generated");
9679
+ if (existsSync11(generatedDir)) {
6473
9680
  try {
6474
9681
  const oldModels = await loadModels({ modelsDir: generatedDir });
6475
9682
  previous = buildMigrationPlan(oldModels, { dialect });
6476
9683
  console.log("-- Comparing with models from generated/ directory");
6477
9684
  } catch (err) {
6478
9685
  console.log("-- No previous models found in generated/ directory, checking state file", err);
6479
- if (existsSync7(statePath)) {
9686
+ if (existsSync11(statePath)) {
6480
9687
  try {
6481
9688
  const raw = readFileSync2(statePath, "utf8");
6482
9689
  const parsed = JSON.parse(raw);
@@ -6484,7 +9691,7 @@ async function generateMigration(dir, opts = {}) {
6484
9691
  } catch {}
6485
9692
  }
6486
9693
  }
6487
- } else if (existsSync7(statePath)) {
9694
+ } else if (existsSync11(statePath)) {
6488
9695
  try {
6489
9696
  const raw = readFileSync2(statePath, "utf8");
6490
9697
  const parsed = JSON.parse(raw);
@@ -6497,16 +9704,16 @@ async function generateMigration(dir, opts = {}) {
6497
9704
  `);
6498
9705
  const hasChanges = sqlStatements.some((stmt) => /\b(?:CREATE|ALTER)\b/i.test(stmt));
6499
9706
  if (opts.apply) {
6500
- const dirPath = mkdtempSync(join5(tmpdir(), "qb-migrate-"));
6501
- const filePath = join5(dirPath, "migration.sql");
9707
+ const dirPath = mkdtempSync(join6(tmpdir(), "qb-migrate-"));
9708
+ const filePath = join6(dirPath, "migration.sql");
6502
9709
  try {
6503
9710
  if (hasChanges) {
6504
- writeFileSync7(filePath, sql);
9711
+ writeFileSync9(filePath, sql);
6505
9712
  console.log("-- Migration applied");
6506
9713
  } else {
6507
9714
  console.log("-- No changes; nothing to apply");
6508
9715
  }
6509
- writeFileSync7(statePath, JSON.stringify({ plan, hash: hashMigrationPlan(plan), updatedAt: new Date().toISOString() }, null, 2));
9716
+ writeFileSync9(statePath, JSON.stringify({ plan, hash: hashMigrationPlan(plan), updatedAt: new Date().toISOString() }, null, 2));
6510
9717
  } catch (err) {
6511
9718
  console.error("-- Migration failed:", err);
6512
9719
  throw err;
@@ -6517,12 +9724,12 @@ async function generateMigration(dir, opts = {}) {
6517
9724
  }
6518
9725
  async function executeMigration(dir) {
6519
9726
  if (!dir) {
6520
- dir = join5(process13.cwd(), "app/Models");
9727
+ dir = join6(process19.cwd(), "app/Models");
6521
9728
  }
6522
9729
  const workspaceRoot = getWorkspaceRoot();
6523
9730
  const sqlDir = ensureSqlDirectory(workspaceRoot);
6524
- const dialect = config2.dialect || "postgres";
6525
- const files = readdirSync3(sqlDir);
9731
+ const dialect = config3.dialect || "postgres";
9732
+ const files = readdirSync4(sqlDir);
6526
9733
  const scriptFiles = files.filter((file2) => file2.endsWith(".sql")).sort();
6527
9734
  if (scriptFiles.length === 0) {
6528
9735
  console.log("-- No migration files found to execute");
@@ -6549,7 +9756,7 @@ async function executeMigration(dir) {
6549
9756
  }
6550
9757
  console.log(`-- Executing ${totalPending} migrations (${permanentMigrations.length} permanent, ${transientMigrations.length} transient)`);
6551
9758
  for (const file2 of permanentMigrations) {
6552
- const filePath = join5(sqlDir, file2);
9759
+ const filePath = join6(sqlDir, file2);
6553
9760
  console.log(`-- Executing: ${file2}`);
6554
9761
  try {
6555
9762
  await qb.file(filePath);
@@ -6561,7 +9768,7 @@ async function executeMigration(dir) {
6561
9768
  }
6562
9769
  }
6563
9770
  for (const file2 of transientMigrations) {
6564
- const filePath = join5(sqlDir, file2);
9771
+ const filePath = join6(sqlDir, file2);
6565
9772
  console.log(`-- Executing: ${file2} (transient)`);
6566
9773
  try {
6567
9774
  await qb.file(filePath);
@@ -6582,7 +9789,7 @@ async function executeMigration(dir) {
6582
9789
  }
6583
9790
  async function resetDatabase(dir, opts = {}) {
6584
9791
  if (!dir) {
6585
- dir = join5(process13.cwd(), "app/Models");
9792
+ dir = join6(process19.cwd(), "app/Models");
6586
9793
  }
6587
9794
  const dialect = opts.dialect || "postgres";
6588
9795
  const driver = getDialectDriver(dialect);
@@ -6669,24 +9876,24 @@ async function resetDatabase(dir, opts = {}) {
6669
9876
  }
6670
9877
  async function deleteMigrationFiles(dir, workspaceRoot, opts = {}) {
6671
9878
  if (!dir) {
6672
- dir = join5(process13.cwd(), "app/Models");
9879
+ dir = join6(process19.cwd(), "app/Models");
6673
9880
  }
6674
9881
  if (!workspaceRoot) {
6675
9882
  workspaceRoot = getWorkspaceRoot();
6676
9883
  }
6677
9884
  const dialect = String(opts.dialect || "postgres");
6678
- const defaultStatePath = join5(dir, `.qb-migrations.${dialect}.json`);
9885
+ const defaultStatePath = join6(dir, `.qb-migrations.${dialect}.json`);
6679
9886
  const statePath = String(opts.state || defaultStatePath);
6680
- if (existsSync7(statePath)) {
9887
+ if (existsSync11(statePath)) {
6681
9888
  unlinkSync(statePath);
6682
9889
  console.log(`-- Removed migration state file: ${statePath}`);
6683
9890
  }
6684
9891
  const sqlDir = getSqlDirectory(workspaceRoot);
6685
- if (existsSync7(sqlDir)) {
6686
- const sqlFiles = readdirSync3(sqlDir);
9892
+ if (existsSync11(sqlDir)) {
9893
+ const sqlFiles = readdirSync4(sqlDir);
6687
9894
  const migrationFiles = sqlFiles.filter((file2) => file2.endsWith(".sql"));
6688
9895
  for (const file2 of migrationFiles) {
6689
- const filePath = join5(sqlDir, file2);
9896
+ const filePath = join6(sqlDir, file2);
6690
9897
  unlinkSync(filePath);
6691
9898
  console.log(`-- Removed migration file: ${file2}`);
6692
9899
  }
@@ -6695,26 +9902,26 @@ async function deleteMigrationFiles(dir, workspaceRoot, opts = {}) {
6695
9902
  }
6696
9903
  async function copyModelsToGenerated(dir, workspaceRoot) {
6697
9904
  if (!dir) {
6698
- dir = join5(process13.cwd(), "app/Models");
9905
+ dir = join6(process19.cwd(), "app/Models");
6699
9906
  }
6700
9907
  if (!workspaceRoot) {
6701
9908
  workspaceRoot = getWorkspaceRoot();
6702
9909
  }
6703
9910
  try {
6704
- const generatedDir = join5(workspaceRoot, "generated");
6705
- if (!existsSync7(generatedDir)) {
6706
- mkdirSync5(generatedDir, { recursive: true });
9911
+ const generatedDir = join6(workspaceRoot, "generated");
9912
+ if (!existsSync11(generatedDir)) {
9913
+ mkdirSync6(generatedDir, { recursive: true });
6707
9914
  console.log("-- Created generated directory");
6708
9915
  }
6709
- const files = readdirSync3(dir);
9916
+ const files = readdirSync4(dir);
6710
9917
  const modelFiles = files.filter((file2) => file2.endsWith(".ts") || file2.endsWith(".js"));
6711
9918
  if (modelFiles.length === 0) {
6712
9919
  console.log("-- No model files found to copy");
6713
9920
  return;
6714
9921
  }
6715
9922
  for (const file2 of modelFiles) {
6716
- const sourcePath = join5(dir, file2);
6717
- const destPath = join5(generatedDir, file2);
9923
+ const sourcePath = join6(dir, file2);
9924
+ const destPath = join6(generatedDir, file2);
6718
9925
  copyFileSync(sourcePath, destPath);
6719
9926
  }
6720
9927
  console.log("-- Model files copied successfully");
@@ -6727,7 +9934,7 @@ function getSqlDirectory(workspaceRoot) {
6727
9934
  if (!workspaceRoot) {
6728
9935
  workspaceRoot = getWorkspaceRoot();
6729
9936
  }
6730
- return join5(workspaceRoot, "database", "sql");
9937
+ return join6(workspaceRoot, "database", "sql");
6731
9938
  }
6732
9939
  async function createMigrationsTable(qb, dialect) {
6733
9940
  const driver = getDialectDriver(dialect);
@@ -6779,24 +9986,24 @@ var init_migrate_generate = __esm(async () => {
6779
9986
  });
6780
9987
 
6781
9988
  // src/actions/migrate-rollback.ts
6782
- import { existsSync as existsSync8, unlinkSync as unlinkSync2 } from "fs";
6783
- import { dirname as dirname5, join as join6 } from "path";
6784
- import process14 from "process";
9989
+ import { existsSync as existsSync12, unlinkSync as unlinkSync2 } from "fs";
9990
+ import { dirname as dirname6, join as join7 } from "path";
9991
+ import process20 from "process";
6785
9992
  function findWorkspaceRoot2(startPath) {
6786
9993
  let currentPath = startPath;
6787
- while (currentPath !== dirname5(currentPath)) {
6788
- if (existsSync8(join6(currentPath, "package.json"))) {
9994
+ while (currentPath !== dirname6(currentPath)) {
9995
+ if (existsSync12(join7(currentPath, "package.json"))) {
6789
9996
  return currentPath;
6790
9997
  }
6791
- currentPath = dirname5(currentPath);
9998
+ currentPath = dirname6(currentPath);
6792
9999
  }
6793
- return process14.cwd();
10000
+ return process20.cwd();
6794
10001
  }
6795
10002
  function getSqlDirectory2(workspaceRoot) {
6796
10003
  if (!workspaceRoot) {
6797
- workspaceRoot = findWorkspaceRoot2(process14.cwd());
10004
+ workspaceRoot = findWorkspaceRoot2(process20.cwd());
6798
10005
  }
6799
- return join6(workspaceRoot, "sql");
10006
+ return join7(workspaceRoot, "sql");
6800
10007
  }
6801
10008
  async function migrateRollback(options = {}) {
6802
10009
  const steps = options.steps || 1;
@@ -6835,8 +10042,8 @@ async function migrateRollback(options = {}) {
6835
10042
  await qb.unsafe(deleteSql, [migration.migration]);
6836
10043
  console.log(`-- \u2713 Removed migration record: ${migration.migration}`);
6837
10044
  const sqlDir = getSqlDirectory2();
6838
- const filePath = join6(sqlDir, migration.migration);
6839
- if (existsSync8(filePath)) {
10045
+ const filePath = join7(sqlDir, migration.migration);
10046
+ if (existsSync12(filePath)) {
6840
10047
  unlinkSync2(filePath);
6841
10048
  console.log(`-- \uD83D\uDDD1\uFE0F Deleted migration file: ${migration.migration}`);
6842
10049
  }
@@ -6861,38 +10068,38 @@ var init_migrate_rollback = __esm(async () => {
6861
10068
  });
6862
10069
 
6863
10070
  // src/actions/migrate-status.ts
6864
- import { existsSync as existsSync9, readdirSync as readdirSync5 } from "fs";
6865
- import { dirname as dirname6, join as join7 } from "path";
6866
- import process15 from "process";
10071
+ import { existsSync as existsSync13, readdirSync as readdirSync6 } from "fs";
10072
+ import { dirname as dirname7, join as join8 } from "path";
10073
+ import process21 from "process";
6867
10074
  function findWorkspaceRoot3(startPath) {
6868
10075
  let currentPath = startPath;
6869
- while (currentPath !== dirname6(currentPath)) {
6870
- if (existsSync9(join7(currentPath, "package.json"))) {
10076
+ while (currentPath !== dirname7(currentPath)) {
10077
+ if (existsSync13(join8(currentPath, "package.json"))) {
6871
10078
  return currentPath;
6872
10079
  }
6873
- currentPath = dirname6(currentPath);
10080
+ currentPath = dirname7(currentPath);
6874
10081
  }
6875
- return process15.cwd();
10082
+ return process21.cwd();
6876
10083
  }
6877
10084
  function getSqlDirectory3(workspaceRoot) {
6878
10085
  if (!workspaceRoot) {
6879
- workspaceRoot = findWorkspaceRoot3(process15.cwd());
10086
+ workspaceRoot = findWorkspaceRoot3(process21.cwd());
6880
10087
  }
6881
- return join7(workspaceRoot, "sql");
10088
+ return join8(workspaceRoot, "sql");
6882
10089
  }
6883
10090
  async function migrateStatus() {
6884
- const dialect = config2.dialect || "postgres";
10091
+ const dialect = config3.dialect || "postgres";
6885
10092
  const driver = getDialectDriver(dialect);
6886
10093
  const sqlDir = getSqlDirectory3();
6887
10094
  console.log("-- Migration Status");
6888
10095
  console.log(`-- Dialect: ${dialect}`);
6889
10096
  console.log(`-- SQL directory: ${sqlDir}`);
6890
10097
  console.log();
6891
- if (!existsSync9(sqlDir)) {
10098
+ if (!existsSync13(sqlDir)) {
6892
10099
  console.log("-- No SQL directory found. No migrations have been created yet.");
6893
10100
  return [];
6894
10101
  }
6895
- const files = readdirSync5(sqlDir);
10102
+ const files = readdirSync6(sqlDir);
6896
10103
  const migrationFiles = files.filter((file2) => file2.endsWith(".sql")).sort();
6897
10104
  if (migrationFiles.length === 0) {
6898
10105
  console.log("-- No migration files found");
@@ -6970,13 +10177,13 @@ var init_migrate_status = __esm(async () => {
6970
10177
  });
6971
10178
 
6972
10179
  // src/actions/model-show.ts
6973
- import { readdirSync as readdirSync6 } from "fs";
6974
- import { extname, join as join8 } from "path";
6975
- import process16 from "process";
10180
+ import { readdirSync as readdirSync7 } from "fs";
10181
+ import { extname, join as join9 } from "path";
10182
+ import process22 from "process";
6976
10183
  async function modelShow(modelName, options = {}) {
6977
- const dir = options.dir || join8(process16.cwd(), "app/Models");
10184
+ const dir = options.dir || join9(process22.cwd(), "app/Models");
6978
10185
  try {
6979
- const files = readdirSync6(dir);
10186
+ const files = readdirSync7(dir);
6980
10187
  const modelFile = files.find((f) => {
6981
10188
  const name = f.replace(extname(f), "");
6982
10189
  return name.toLowerCase() === modelName.toLowerCase();
@@ -6986,7 +10193,7 @@ async function modelShow(modelName, options = {}) {
6986
10193
  console.log(`Available models: ${files.filter((f) => [".ts", ".js"].includes(extname(f))).map((f) => f.replace(extname(f), "")).join(", ")}`);
6987
10194
  return;
6988
10195
  }
6989
- const modelPath = join8(dir, modelFile);
10196
+ const modelPath = join9(dir, modelFile);
6990
10197
  const module = await import(modelPath);
6991
10198
  const model = module.default || module[Object.keys(module)[0]];
6992
10199
  if (!model || !model.name) {
@@ -7093,17 +10300,17 @@ var init_ping = __esm(async () => {
7093
10300
  });
7094
10301
 
7095
10302
  // src/actions/query-explain-all.ts
7096
- import { readdirSync as readdirSync7, readFileSync as readFileSync3, statSync } from "fs";
7097
- import { extname as extname2, join as join9 } from "path";
10303
+ import { readdirSync as readdirSync8, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
10304
+ import { extname as extname2, join as join10 } from "path";
7098
10305
  async function queryExplainAll(path, options = {}) {
7099
10306
  const results = [];
7100
10307
  try {
7101
- const stat2 = statSync(path);
10308
+ const stat3 = statSync2(path);
7102
10309
  let files = [];
7103
- if (stat2.isDirectory()) {
7104
- const allFiles = readdirSync7(path);
7105
- files = allFiles.filter((f) => extname2(f) === ".sql").map((f) => join9(path, f));
7106
- } else if (stat2.isFile() && extname2(path) === ".sql") {
10310
+ if (stat3.isDirectory()) {
10311
+ const allFiles = readdirSync8(path);
10312
+ files = allFiles.filter((f) => extname2(f) === ".sql").map((f) => join10(path, f));
10313
+ } else if (stat3.isFile() && extname2(path) === ".sql") {
7107
10314
  files = [path];
7108
10315
  } else {
7109
10316
  console.error("Path must be a .sql file or directory containing .sql files");
@@ -7186,11 +10393,11 @@ var init_query_explain_all = __esm(async () => {
7186
10393
  });
7187
10394
 
7188
10395
  // src/actions/relation-diagram.ts
7189
- import { writeFileSync as writeFileSync8 } from "fs";
7190
- import { join as join10 } from "path";
7191
- import process17 from "process";
10396
+ import { writeFileSync as writeFileSync10 } from "fs";
10397
+ import { join as join11 } from "path";
10398
+ import process23 from "process";
7192
10399
  async function relationDiagram(options = {}) {
7193
- const dir = options.dir || join10(process17.cwd(), "app/Models");
10400
+ const dir = options.dir || join11(process23.cwd(), "app/Models");
7194
10401
  const format = options.format || "mermaid";
7195
10402
  try {
7196
10403
  const models = await loadModels({ modelsDir: dir });
@@ -7208,7 +10415,7 @@ async function relationDiagram(options = {}) {
7208
10415
  return "";
7209
10416
  }
7210
10417
  if (options.output) {
7211
- writeFileSync8(options.output, diagram, "utf8");
10418
+ writeFileSync10(options.output, diagram, "utf8");
7212
10419
  console.log(`\u2713 Diagram written to: ${options.output}`);
7213
10420
  } else {
7214
10421
  console.log(diagram);
@@ -7310,29 +10517,29 @@ var init_relation_diagram = __esm(async () => {
7310
10517
  });
7311
10518
 
7312
10519
  // src/actions/seed.ts
7313
- import { existsSync as existsSync10, mkdirSync as mkdirSync6, readdirSync as readdirSync8, writeFileSync as writeFileSync9 } from "fs";
7314
- import { dirname as dirname7, join as join11 } from "path";
7315
- import process18 from "process";
10520
+ import { existsSync as existsSync14, mkdirSync as mkdirSync7, readdirSync as readdirSync9, writeFileSync as writeFileSync11 } from "fs";
10521
+ import { dirname as dirname8, join as join12 } from "path";
10522
+ import process24 from "process";
7316
10523
  function findWorkspaceRoot4(startPath) {
7317
10524
  let currentPath = startPath;
7318
- while (currentPath !== dirname7(currentPath)) {
7319
- if (existsSync10(join11(currentPath, "package.json"))) {
10525
+ while (currentPath !== dirname8(currentPath)) {
10526
+ if (existsSync14(join12(currentPath, "package.json"))) {
7320
10527
  return currentPath;
7321
10528
  }
7322
- currentPath = dirname7(currentPath);
10529
+ currentPath = dirname8(currentPath);
7323
10530
  }
7324
- return process18.cwd();
10531
+ return process24.cwd();
7325
10532
  }
7326
10533
  async function loadSeeders(seedersDir) {
7327
- if (!existsSync10(seedersDir)) {
10534
+ if (!existsSync14(seedersDir)) {
7328
10535
  console.log(`-- Seeders directory not found: ${seedersDir}`);
7329
10536
  return [];
7330
10537
  }
7331
- const files = readdirSync8(seedersDir);
10538
+ const files = readdirSync9(seedersDir);
7332
10539
  const seederFiles = files.filter((file2) => (file2.endsWith(".ts") || file2.endsWith(".js")) && file2 !== "index.ts" && file2 !== "index.js");
7333
10540
  const seeders = [];
7334
10541
  for (const file2 of seederFiles) {
7335
- const filePath = join11(seedersDir, file2);
10542
+ const filePath = join12(seedersDir, file2);
7336
10543
  try {
7337
10544
  const module = await import(filePath);
7338
10545
  const SeederClass = module.default || module[Object.keys(module)[0]];
@@ -7352,10 +10559,10 @@ async function loadSeeders(seedersDir) {
7352
10559
  seeders.sort((a, b) => a.instance.order - b.instance.order);
7353
10560
  return seeders;
7354
10561
  }
7355
- async function runSeeders(config3 = {}) {
7356
- const workspaceRoot = findWorkspaceRoot4(process18.cwd());
7357
- const seedersDir = config3.seedersDir || join11(workspaceRoot, "database/seeders");
7358
- const verbose = config3.verbose ?? true;
10562
+ async function runSeeders(config4 = {}) {
10563
+ const workspaceRoot = findWorkspaceRoot4(process24.cwd());
10564
+ const seedersDir = config4.seedersDir || join12(workspaceRoot, "database/seeders");
10565
+ const verbose = config4.verbose ?? true;
7359
10566
  if (verbose) {
7360
10567
  console.log("-- Running seeders...");
7361
10568
  console.log(`-- Seeders directory: ${seedersDir}`);
@@ -7388,8 +10595,8 @@ async function runSeeders(config3 = {}) {
7388
10595
  }
7389
10596
  }
7390
10597
  async function runSeeder(className, options = {}) {
7391
- const workspaceRoot = findWorkspaceRoot4(process18.cwd());
7392
- const seedersDir = join11(workspaceRoot, "database/seeders");
10598
+ const workspaceRoot = findWorkspaceRoot4(process24.cwd());
10599
+ const seedersDir = join12(workspaceRoot, "database/seeders");
7393
10600
  const verbose = options.verbose ?? true;
7394
10601
  if (verbose) {
7395
10602
  console.log(`-- Running seeder: ${className}`);
@@ -7412,17 +10619,17 @@ async function runSeeder(className, options = {}) {
7412
10619
  }
7413
10620
  }
7414
10621
  async function makeSeeder(name) {
7415
- const workspaceRoot = findWorkspaceRoot4(process18.cwd());
7416
- const seedersDir = join11(workspaceRoot, "database/seeders");
7417
- if (!existsSync10(seedersDir)) {
7418
- mkdirSync6(seedersDir, { recursive: true });
10622
+ const workspaceRoot = findWorkspaceRoot4(process24.cwd());
10623
+ const seedersDir = join12(workspaceRoot, "database/seeders");
10624
+ if (!existsSync14(seedersDir)) {
10625
+ mkdirSync7(seedersDir, { recursive: true });
7419
10626
  console.log(`-- Created seeders directory: ${seedersDir}`);
7420
10627
  }
7421
10628
  const baseName = name.replace(/Seeder$/i, "");
7422
10629
  const className = `${baseName}Seeder`;
7423
10630
  const fileName = `${className}.ts`;
7424
- const filePath = join11(seedersDir, fileName);
7425
- if (existsSync10(filePath)) {
10631
+ const filePath = join12(seedersDir, fileName);
10632
+ if (existsSync14(filePath)) {
7426
10633
  console.error(`-- Seeder already exists: ${filePath}`);
7427
10634
  throw new Error(`Seeder already exists: ${filePath}`);
7428
10635
  }
@@ -7472,13 +10679,13 @@ export default class ${className} extends Seeder {
7472
10679
  }
7473
10680
  }
7474
10681
  `;
7475
- writeFileSync9(filePath, template);
10682
+ writeFileSync11(filePath, template);
7476
10683
  console.log(`-- \u2713 Created seeder: ${filePath}`);
7477
10684
  }
7478
10685
  async function freshDatabase(options = {}) {
7479
- const workspaceRoot = findWorkspaceRoot4(process18.cwd());
7480
- const modelsDir = options.modelsDir || join11(workspaceRoot, "app/Models");
7481
- const seedersDir = options.seedersDir || join11(workspaceRoot, "database/seeders");
10686
+ const workspaceRoot = findWorkspaceRoot4(process24.cwd());
10687
+ const modelsDir = options.modelsDir || join12(workspaceRoot, "app/Models");
10688
+ const seedersDir = options.seedersDir || join12(workspaceRoot, "database/seeders");
7482
10689
  const verbose = options.verbose ?? true;
7483
10690
  try {
7484
10691
  const { resetDatabase: resetDatabase2, generateMigration: generateMigration2, executeMigration: executeMigration2 } = await init_migrate().then(() => exports_migrate);
@@ -7511,8 +10718,8 @@ var init_seed = __esm(async () => {
7511
10718
  function sql(dir, table, opts = {}) {
7512
10719
  const models = loadModels({ modelsDir: dir });
7513
10720
  const dbSchema = buildDatabaseSchema(models);
7514
- if (config2.debug)
7515
- config2.debug.captureText = true;
10721
+ if (config3.debug)
10722
+ config3.debug.captureText = true;
7516
10723
  const qb = createQueryBuilder({ schema: dbSchema });
7517
10724
  const s = qb.selectFrom(table).limit(Number(opts.limit || 10)).toText?.() ?? "";
7518
10725
  console.log(s || "[query]");
@@ -7538,24 +10745,24 @@ var init_unsafe = __esm(async () => {
7538
10745
  });
7539
10746
 
7540
10747
  // src/actions/validate.ts
7541
- import { existsSync as existsSync11 } from "fs";
7542
- import { dirname as dirname8, join as join12 } from "path";
7543
- import process19 from "process";
10748
+ import { existsSync as existsSync15 } from "fs";
10749
+ import { dirname as dirname9, join as join13 } from "path";
10750
+ import process25 from "process";
7544
10751
  function findWorkspaceRoot5(startPath) {
7545
10752
  let currentPath = startPath;
7546
- while (currentPath !== dirname8(currentPath)) {
7547
- if (existsSync11(join12(currentPath, "package.json"))) {
10753
+ while (currentPath !== dirname9(currentPath)) {
10754
+ if (existsSync15(join13(currentPath, "package.json"))) {
7548
10755
  return currentPath;
7549
10756
  }
7550
- currentPath = dirname8(currentPath);
10757
+ currentPath = dirname9(currentPath);
7551
10758
  }
7552
- return process19.cwd();
10759
+ return process25.cwd();
7553
10760
  }
7554
10761
  async function validateSchema(dir) {
7555
10762
  if (!dir) {
7556
- dir = join12(findWorkspaceRoot5(process19.cwd()), "app/Models");
10763
+ dir = join13(findWorkspaceRoot5(process25.cwd()), "app/Models");
7557
10764
  }
7558
- const dialect = config2.dialect || "postgres";
10765
+ const dialect = config3.dialect || "postgres";
7559
10766
  console.log("-- Validating Schema");
7560
10767
  console.log(`-- Models directory: ${dir}`);
7561
10768
  console.log(`-- Dialect: ${dialect}`);
@@ -7811,17 +11018,17 @@ function buildDatabaseSchema(models) {
7811
11018
  }
7812
11019
 
7813
11020
  // src/loader.ts
7814
- import { readdirSync as readdirSync9, statSync as statSync2 } from "fs";
11021
+ import { readdirSync as readdirSync10, statSync as statSync3 } from "fs";
7815
11022
  import { basename, extname as extname3 } from "path";
7816
- import process20 from "process";
11023
+ import process26 from "process";
7817
11024
  async function loadModels(options) {
7818
- const cwd = options.cwd ?? process20.cwd();
11025
+ const cwd = options.cwd ?? process26.cwd();
7819
11026
  const dir = options.modelsDir.startsWith("/") ? options.modelsDir : `${cwd}/${options.modelsDir}`;
7820
11027
  const result = {};
7821
- const entries = readdirSync9(dir);
11028
+ const entries = readdirSync10(dir);
7822
11029
  for (const entry of entries) {
7823
11030
  const full = `${dir}/${entry}`;
7824
- const st = statSync2(full);
11031
+ const st = statSync3(full);
7825
11032
  if (st.isDirectory())
7826
11033
  continue;
7827
11034
  const ext = extname3(full);
@@ -7895,24 +11102,24 @@ function buildSchemaMeta(models) {
7895
11102
  }
7896
11103
 
7897
11104
  // src/migrations.ts
7898
- import { existsSync as existsSync12, mkdirSync as mkdirSync7, writeFileSync as writeFileSync10 } from "fs";
7899
- import { dirname as dirname9, join as join13 } from "path";
7900
- import process21 from "process";
11105
+ import { existsSync as existsSync16, mkdirSync as mkdirSync8, writeFileSync as writeFileSync12 } from "fs";
11106
+ import { dirname as dirname10, join as join14 } from "path";
11107
+ import process27 from "process";
7901
11108
  function findWorkspaceRoot6(startPath) {
7902
11109
  let currentPath = startPath;
7903
- while (currentPath !== dirname9(currentPath)) {
7904
- if (existsSync12(join13(currentPath, "package.json"))) {
11110
+ while (currentPath !== dirname10(currentPath)) {
11111
+ if (existsSync16(join14(currentPath, "package.json"))) {
7905
11112
  return currentPath;
7906
11113
  }
7907
- currentPath = dirname9(currentPath);
11114
+ currentPath = dirname10(currentPath);
7908
11115
  }
7909
- return process21.cwd();
11116
+ return process27.cwd();
7910
11117
  }
7911
11118
  function ensureSqlDirectory2() {
7912
- const workspaceRoot = findWorkspaceRoot6(process21.cwd());
7913
- const sqlDir = join13(workspaceRoot, "database", "sql");
7914
- if (!existsSync12(sqlDir)) {
7915
- mkdirSync7(sqlDir, { recursive: true });
11119
+ const workspaceRoot = findWorkspaceRoot6(process27.cwd());
11120
+ const sqlDir = join14(workspaceRoot, "database", "sql");
11121
+ if (!existsSync16(sqlDir)) {
11122
+ mkdirSync8(sqlDir, { recursive: true });
7916
11123
  console.log(`-- Created SQL directory: ${sqlDir}`);
7917
11124
  }
7918
11125
  return sqlDir;
@@ -7925,8 +11132,8 @@ function createMigrationFile(statement, fileName) {
7925
11132
  const timestamp = baseTimestamp + migrationCounter;
7926
11133
  migrationCounter++;
7927
11134
  const fullFileName = `${timestamp}-${fileName}.sql`;
7928
- const filePath = join13(sqlDir, fullFileName);
7929
- writeFileSync10(filePath, statement);
11135
+ const filePath = join14(sqlDir, fullFileName);
11136
+ writeFileSync12(filePath, statement);
7930
11137
  console.log(`-- Migration file created: ${fullFileName}`);
7931
11138
  migrationsCreatedCount++;
7932
11139
  return true;
@@ -8487,13 +11694,13 @@ export {
8487
11694
  defineSeeder,
8488
11695
  defineModels,
8489
11696
  defineModel,
8490
- defaultConfig2 as defaultConfig,
11697
+ defaultConfig3 as defaultConfig,
8491
11698
  dbWipe,
8492
11699
  dbStats,
8493
11700
  dbOptimize,
8494
11701
  dbInfo,
8495
11702
  createQueryBuilder,
8496
- config2 as config,
11703
+ config3 as config,
8497
11704
  clearQueryCache,
8498
11705
  checkSchema,
8499
11706
  cacheStats,