bun-query-builder 0.1.6 → 0.1.7

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 +3492 -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.2/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: /^https?:\/\// },
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, 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,271 @@ 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
+ log2 = new Logger2("bunfig", {
5069
+ showTags: true
5070
+ });
5071
+ globalConfigLoader = new ConfigLoader;
5072
+ defaultConfigDir3 = resolve7(process12.cwd(), "config");
5073
+ defaultGeneratedDir3 = resolve7(process12.cwd(), "src/generated");
1868
5074
  });
1869
5075
 
1870
5076
  // src/config.ts
1871
- var defaultConfig2, config2;
5077
+ var defaultConfig3, config3;
1872
5078
  var init_config = __esm(async () => {
1873
5079
  await init_dist();
1874
- defaultConfig2 = {
5080
+ defaultConfig3 = {
1875
5081
  verbose: true,
1876
5082
  dialect: "postgres",
1877
5083
  database: {
@@ -1928,16 +5134,16 @@ var init_config = __esm(async () => {
1928
5134
  defaultFilter: true
1929
5135
  }
1930
5136
  };
1931
- config2 = await loadConfig3({
5137
+ config3 = await loadConfig5({
1932
5138
  name: "query-builder",
1933
5139
  alias: "qb",
1934
- defaultConfig: defaultConfig2
5140
+ defaultConfig: defaultConfig3
1935
5141
  });
1936
5142
  });
1937
5143
 
1938
5144
  // src/db.ts
1939
5145
  var {SQL } = globalThis.Bun;
1940
- import process7 from "process";
5146
+ import process13 from "process";
1941
5147
  function createConnectionString(dialect, dbConfig) {
1942
5148
  if (dbConfig.url) {
1943
5149
  return dbConfig.url;
@@ -1958,12 +5164,12 @@ function createConnectionString(dialect, dbConfig) {
1958
5164
  }
1959
5165
  }
1960
5166
  function getBunSql() {
1961
- const connectionString = createConnectionString(config2.dialect, config2.database);
5167
+ const connectionString = createConnectionString(config3.dialect, config3.database);
1962
5168
  try {
1963
5169
  const sql = new SQL(connectionString);
1964
5170
  if (sql && typeof sql.catch === "function") {
1965
5171
  sql.catch((error) => {
1966
- if (config2.verbose && !error.message.includes("database") && !error.message.includes("does not exist")) {
5172
+ if (config3.verbose && !error.message.includes("database") && !error.message.includes("does not exist")) {
1967
5173
  console.warn(`[query-builder] Database connection error: ${error.message}`);
1968
5174
  }
1969
5175
  });
@@ -2007,14 +5213,14 @@ var _bunSqlInstance = null, bunSql;
2007
5213
  var init_db = __esm(async () => {
2008
5214
  await init_config();
2009
5215
  bunSql = getOrCreateBunSql();
2010
- if (typeof process7 !== "undefined" && process7.on) {
2011
- const existingHandler = process7.listeners("unhandledRejection").find((h) => h.name === "sqlConnectionErrorHandler");
5216
+ if (typeof process13 !== "undefined" && process13.on) {
5217
+ const existingHandler = process13.listeners("unhandledRejection").find((h) => h.name === "sqlConnectionErrorHandler");
2012
5218
  if (!existingHandler) {
2013
5219
  let sqlConnectionErrorHandler = function(reason) {
2014
5220
  if (reason && (reason.message?.includes("database") || reason.message?.includes("does not exist") || reason.code === "ERR_POSTGRES_SERVER_ERROR" || reason.code === "3D000")) {}
2015
5221
  };
2016
5222
  Object.defineProperty(sqlConnectionErrorHandler, "name", { value: "sqlConnectionErrorHandler" });
2017
- process7.on("unhandledRejection", sqlConnectionErrorHandler);
5223
+ process13.on("unhandledRejection", sqlConnectionErrorHandler);
2018
5224
  }
2019
5225
  }
2020
5226
  });
@@ -2233,7 +5439,7 @@ function matchesSqlState(err, states) {
2233
5439
  return states.includes(code);
2234
5440
  }
2235
5441
  function sleep(ms) {
2236
- return new Promise((resolve4) => setTimeout(resolve4, ms));
5442
+ return new Promise((resolve8) => setTimeout(resolve8, ms));
2237
5443
  }
2238
5444
  function computeBackoffMs(attempt, cfg) {
2239
5445
  const base = Math.max(1, cfg?.baseMs ?? 50);
@@ -2313,16 +5519,16 @@ function createQueryBuilder(state) {
2313
5519
  return _sql`${q} WHERE ${condition}`;
2314
5520
  }
2315
5521
  function computeSqlText(q) {
2316
- const prev = config2.debug?.captureText;
2317
- if (config2.debug)
2318
- config2.debug.captureText = true;
5522
+ const prev = config3.debug?.captureText;
5523
+ if (config3.debug)
5524
+ config3.debug.captureText = true;
2319
5525
  const s = String(q);
2320
- if (config2.debug)
2321
- config2.debug.captureText = prev;
5526
+ if (config3.debug)
5527
+ config3.debug.captureText = prev;
2322
5528
  return s;
2323
5529
  }
2324
5530
  function runWithHooks(q, kind, opts) {
2325
- const hooks = config2.hooks;
5531
+ const hooks = config3.hooks;
2326
5532
  const hasHooks = hooks && (hooks.onQueryStart || hooks.onQueryEnd || hooks.onQueryError || hooks.startSpan);
2327
5533
  const hasTimeoutOrSignal = opts?.timeoutMs && opts.timeoutMs > 0 || opts?.signal;
2328
5534
  if (!hasHooks && !hasTimeoutOrSignal) {
@@ -2671,7 +5877,7 @@ function createQueryBuilder(state) {
2671
5877
  }
2672
5878
  if (normalizedRelations.length === 0)
2673
5879
  return this;
2674
- const maxEagerLoad = config2.relations.maxEagerLoad ?? 50;
5880
+ const maxEagerLoad = config3.relations.maxEagerLoad ?? 50;
2675
5881
  if (normalizedRelations.length > maxEagerLoad) {
2676
5882
  throw new Error(`[query-builder] Too many relationships to eager load (${normalizedRelations.length}). Maximum allowed: ${maxEagerLoad}`);
2677
5883
  }
@@ -2680,7 +5886,7 @@ function createQueryBuilder(state) {
2680
5886
  const loadedRelationships = new Set;
2681
5887
  const relationConditions = new Map;
2682
5888
  const singularize = (name) => {
2683
- if (config2.relations.singularizeStrategy === "none")
5889
+ if (config3.relations.singularizeStrategy === "none")
2684
5890
  return name;
2685
5891
  return name.endsWith("s") ? name.slice(0, -1) : name;
2686
5892
  };
@@ -2702,7 +5908,7 @@ function createQueryBuilder(state) {
2702
5908
  ];
2703
5909
  };
2704
5910
  const addJoin = (fromTable, relationKey, depth = 0, condition) => {
2705
- const maxDepth = config2.relations.maxDepth ?? 10;
5911
+ const maxDepth = config3.relations.maxDepth ?? 10;
2706
5912
  if (depth >= maxDepth) {
2707
5913
  throw new Error(`[query-builder] Maximum relationship depth (${maxDepth}) exceeded at '${relationKey}'. Consider using separate queries or increasing maxDepth.`);
2708
5914
  }
@@ -2712,8 +5918,8 @@ function createQueryBuilder(state) {
2712
5918
  }
2713
5919
  const _buildConditionalJoin = (baseJoinCondition, targetTable2) => {
2714
5920
  let joinCondition = baseJoinCondition;
2715
- if (config2.softDeletes?.enabled && config2.softDeletes?.defaultFilter) {
2716
- const softDeleteColumn = config2.softDeletes.column || "deleted_at";
5921
+ if (config3.softDeletes?.enabled && config3.softDeletes?.defaultFilter) {
5922
+ const softDeleteColumn = config3.softDeletes.column || "deleted_at";
2717
5923
  joinCondition = `${joinCondition} AND ${targetTable2}.${softDeleteColumn} IS NULL`;
2718
5924
  }
2719
5925
  if (!condition)
@@ -2733,8 +5939,8 @@ function createQueryBuilder(state) {
2733
5939
  return joinCondition;
2734
5940
  };
2735
5941
  const addSoftDeleteCheck = (table2) => {
2736
- if (config2.softDeletes?.enabled && config2.softDeletes?.defaultFilter) {
2737
- const softDeleteColumn = config2.softDeletes.column || "deleted_at";
5942
+ if (config3.softDeletes?.enabled && config3.softDeletes?.defaultFilter) {
5943
+ const softDeleteColumn = config3.softDeletes.column || "deleted_at";
2738
5944
  return ` AND ${table2}.${softDeleteColumn} IS NULL`;
2739
5945
  }
2740
5946
  return "";
@@ -2759,7 +5965,7 @@ function createQueryBuilder(state) {
2759
5965
  throw new Error(`[query-builder] Relationship '${relationKey}' not found on table '${fromTable}'.${suggestion}`);
2760
5966
  }
2761
5967
  }
2762
- if (config2.relations.detectCycles !== false) {
5968
+ if (config3.relations.detectCycles !== false) {
2763
5969
  const cycleKey = `${fromTable}->${childTable}`;
2764
5970
  if (visitedTables.has(cycleKey)) {
2765
5971
  throw new Error(`[query-builder] Circular relationship detected: ${cycleKey}. This would cause an infinite loop.`);
@@ -3168,7 +6374,7 @@ function createQueryBuilder(state) {
3168
6374
  return this;
3169
6375
  },
3170
6376
  whereJsonPath(path, op, value) {
3171
- const dialect = config2.dialect;
6377
+ const dialect = config3.dialect;
3172
6378
  if (dialect === "postgres") {
3173
6379
  built = sql`${built} WHERE ${sql(path)} ${op} ${value}`;
3174
6380
  } else if (dialect === "mysql") {
@@ -3185,7 +6391,7 @@ function createQueryBuilder(state) {
3185
6391
  return this;
3186
6392
  },
3187
6393
  whereILike(column, pattern) {
3188
- if (config2.dialect === "postgres") {
6394
+ if (config3.dialect === "postgres") {
3189
6395
  built = sql`${built} WHERE ${sql(String(column))} ILIKE ${pattern}`;
3190
6396
  addWhereText("WHERE", `${String(column)} ILIKE ?`);
3191
6397
  } else {
@@ -3202,7 +6408,7 @@ function createQueryBuilder(state) {
3202
6408
  return this;
3203
6409
  },
3204
6410
  orWhereILike(column, pattern) {
3205
- if (config2.dialect === "postgres") {
6411
+ if (config3.dialect === "postgres") {
3206
6412
  built = sql`${built} OR ${sql(String(column))} ILIKE ${pattern}`;
3207
6413
  addWhereText("OR", `${String(column)} ILIKE ?`);
3208
6414
  } else {
@@ -3219,7 +6425,7 @@ function createQueryBuilder(state) {
3219
6425
  return this;
3220
6426
  },
3221
6427
  whereNotILike(column, pattern) {
3222
- if (config2.dialect === "postgres") {
6428
+ if (config3.dialect === "postgres") {
3223
6429
  built = sql`${built} WHERE ${sql(String(column))} NOT ILIKE ${pattern}`;
3224
6430
  addWhereText("WHERE", `${String(column)} NOT ILIKE ?`);
3225
6431
  } else {
@@ -3236,7 +6442,7 @@ function createQueryBuilder(state) {
3236
6442
  return this;
3237
6443
  },
3238
6444
  orWhereNotILike(column, pattern) {
3239
- if (config2.dialect === "postgres") {
6445
+ if (config3.dialect === "postgres") {
3240
6446
  built = sql`${built} OR ${sql(String(column))} NOT ILIKE ${pattern}`;
3241
6447
  addWhereText("OR", `${String(column)} NOT ILIKE ?`);
3242
6448
  } else {
@@ -3448,7 +6654,7 @@ function createQueryBuilder(state) {
3448
6654
  return this;
3449
6655
  },
3450
6656
  inRandomOrder() {
3451
- const rnd = config2.sql.randomFunction === "RAND()" ? sql`RAND()` : sql`RANDOM()`;
6657
+ const rnd = config3.sql.randomFunction === "RAND()" ? sql`RAND()` : sql`RANDOM()`;
3452
6658
  built = sql`${built} ORDER BY ${rnd}`;
3453
6659
  return this;
3454
6660
  },
@@ -3457,12 +6663,12 @@ function createQueryBuilder(state) {
3457
6663
  return this;
3458
6664
  },
3459
6665
  latest(column) {
3460
- const col = column ?? config2.timestamps.defaultOrderColumn;
6666
+ const col = column ?? config3.timestamps.defaultOrderColumn;
3461
6667
  built = sql`${built} ORDER BY ${sql(String(col))} DESC`;
3462
6668
  return this;
3463
6669
  },
3464
6670
  oldest(column) {
3465
- const col = column ?? config2.timestamps.defaultOrderColumn;
6671
+ const col = column ?? config3.timestamps.defaultOrderColumn;
3466
6672
  built = sql`${built} ORDER BY ${sql(String(col))} ASC`;
3467
6673
  return this;
3468
6674
  },
@@ -3529,7 +6735,7 @@ function createQueryBuilder(state) {
3529
6735
  for (const jt of joinedTables) {
3530
6736
  const cols = Object.keys(schema[jt]?.columns ?? {});
3531
6737
  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}`;
6738
+ 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
6739
  parts.push(sql`${sql(`${jt}.${c}`)} AS ${sql(alias)}`);
3534
6740
  }
3535
6741
  }
@@ -3717,7 +6923,7 @@ function createQueryBuilder(state) {
3717
6923
  onlyTrashed() {
3718
6924
  includeTrashed = true;
3719
6925
  onlyTrashed = true;
3720
- const softDeleteColumn = config2.softDeletes?.column || "deleted_at";
6926
+ const softDeleteColumn = config3.softDeletes?.column || "deleted_at";
3721
6927
  if (text.includes("WHERE")) {
3722
6928
  text = text.replace(/WHERE/, `WHERE ${table}.${softDeleteColumn} IS NOT NULL AND`);
3723
6929
  } else {
@@ -3777,7 +6983,7 @@ function createQueryBuilder(state) {
3777
6983
  },
3778
6984
  async get() {
3779
6985
  built = whereParams.length > 0 ? _sql.unsafe(text, whereParams) : _sql.unsafe(text);
3780
- if (!config2.softDeletes?.enabled && !useCache && !timeoutMs && !abortSignal && !config2.hooks) {
6986
+ if (!config3.softDeletes?.enabled && !useCache && !timeoutMs && !abortSignal && !config3.hooks) {
3781
6987
  const stmt = built._stmt;
3782
6988
  const params = built._params;
3783
6989
  if (stmt) {
@@ -3785,12 +6991,12 @@ function createQueryBuilder(state) {
3785
6991
  }
3786
6992
  return built.execute();
3787
6993
  }
3788
- if (!config2.softDeletes?.enabled && !useCache && !timeoutMs && !abortSignal) {
6994
+ if (!config3.softDeletes?.enabled && !useCache && !timeoutMs && !abortSignal) {
3789
6995
  return runWithHooks(built, "select");
3790
6996
  }
3791
6997
  let finalQuery = built;
3792
- if (config2.softDeletes?.enabled && config2.softDeletes.defaultFilter && !includeTrashed) {
3793
- const col = config2.softDeletes.column;
6998
+ if (config3.softDeletes?.enabled && config3.softDeletes.defaultFilter && !includeTrashed) {
6999
+ const col = config3.softDeletes.column;
3794
7000
  const tbl = String(table);
3795
7001
  const hasCol = schema ? Boolean(schema[tbl]?.columns?.[col]) : true;
3796
7002
  if (hasCol && !SQL_PATTERNS.DELETED_AT.test(text)) {
@@ -3921,7 +7127,7 @@ function createQueryBuilder(state) {
3921
7127
  return this;
3922
7128
  },
3923
7129
  sharedLock() {
3924
- const syntax = config2.sql.sharedLockSyntax === "LOCK IN SHARE MODE" ? sql`LOCK IN SHARE MODE` : sql`FOR SHARE`;
7130
+ const syntax = config3.sql.sharedLockSyntax === "LOCK IN SHARE MODE" ? sql`LOCK IN SHARE MODE` : sql`FOR SHARE`;
3925
7131
  built = sql`${built} ${syntax}`;
3926
7132
  return this;
3927
7133
  },
@@ -3989,7 +7195,7 @@ function createQueryBuilder(state) {
3989
7195
  }
3990
7196
  return {
3991
7197
  configure(opts) {
3992
- Object.assign(config2, opts);
7198
+ Object.assign(config3, opts);
3993
7199
  return this;
3994
7200
  },
3995
7201
  id(name) {
@@ -4417,13 +7623,13 @@ function createQueryBuilder(state) {
4417
7623
  },
4418
7624
  async execute() {
4419
7625
  try {
4420
- await config2.hooks?.beforeDelete?.({ table: String(table), where: whereCondition });
7626
+ await config3.hooks?.beforeDelete?.({ table: String(table), where: whereCondition });
4421
7627
  } catch (err) {
4422
7628
  throw err;
4423
7629
  }
4424
7630
  const result = await runWithHooks(built, "delete");
4425
7631
  try {
4426
- await config2.hooks?.afterDelete?.({ table: String(table), where: whereCondition, result });
7632
+ await config3.hooks?.afterDelete?.({ table: String(table), where: whereCondition, result });
4427
7633
  } catch {}
4428
7634
  return result;
4429
7635
  }
@@ -4457,7 +7663,7 @@ function createQueryBuilder(state) {
4457
7663
  return _sql(strings, ...values).simple();
4458
7664
  },
4459
7665
  async advisoryLock(key) {
4460
- if (config2.dialect !== "postgres")
7666
+ if (config3.dialect !== "postgres")
4461
7667
  return;
4462
7668
  const s = String(key);
4463
7669
  let hash = 7;
@@ -4468,7 +7674,7 @@ function createQueryBuilder(state) {
4468
7674
  await runWithHooks(q, "raw");
4469
7675
  },
4470
7676
  async tryAdvisoryLock(key) {
4471
- if (config2.dialect !== "postgres")
7677
+ if (config3.dialect !== "postgres")
4472
7678
  return false;
4473
7679
  const s = String(key);
4474
7680
  let hash = 7;
@@ -4520,7 +7726,7 @@ function createQueryBuilder(state) {
4520
7726
  for (let i = 0;i < attempts; i++) {
4521
7727
  if (await this.ping())
4522
7728
  return;
4523
- await new Promise((resolve4) => setTimeout(resolve4, delay));
7729
+ await new Promise((resolve8) => setTimeout(resolve8, delay));
4524
7730
  }
4525
7731
  throw new Error("Database not ready after waiting");
4526
7732
  },
@@ -4610,7 +7816,7 @@ function createQueryBuilder(state) {
4610
7816
  return built.execute();
4611
7817
  },
4612
7818
  async insertGetId(table, values, idColumn = "id") {
4613
- if (config2.dialect === "mysql") {
7819
+ if (config3.dialect === "mysql") {
4614
7820
  const insertQuery = bunSql`INSERT INTO ${bunSql(String(table))} ${bunSql(values)}`;
4615
7821
  const result = await insertQuery.execute();
4616
7822
  if (result && typeof result === "object" && "insertId" in result) {
@@ -4685,23 +7891,23 @@ function createQueryBuilder(state) {
4685
7891
  async rawQuery(query) {
4686
7892
  const start = Date.now();
4687
7893
  try {
4688
- config2.hooks?.onQueryStart?.({ sql: query, kind: "raw" });
7894
+ config3.hooks?.onQueryStart?.({ sql: query, kind: "raw" });
4689
7895
  const res = await bunSql.unsafe(query);
4690
- config2.hooks?.onQueryEnd?.({ sql: query, durationMs: Date.now() - start, kind: "raw" });
7896
+ config3.hooks?.onQueryEnd?.({ sql: query, durationMs: Date.now() - start, kind: "raw" });
4691
7897
  return res;
4692
7898
  } catch (err) {
4693
- config2.hooks?.onQueryError?.({ sql: query, error: err, durationMs: Date.now() - start, kind: "raw" });
7899
+ config3.hooks?.onQueryError?.({ sql: query, error: err, durationMs: Date.now() - start, kind: "raw" });
4694
7900
  throw err;
4695
7901
  }
4696
7902
  },
4697
7903
  async create(table, values) {
4698
7904
  const pk = meta?.primaryKeys[String(table)] ?? "id";
4699
7905
  try {
4700
- await config2.hooks?.beforeCreate?.({ table: String(table), data: values });
7906
+ await config3.hooks?.beforeCreate?.({ table: String(table), data: values });
4701
7907
  } catch (err) {
4702
7908
  throw err;
4703
7909
  }
4704
- if (config2.dialect === "postgres") {
7910
+ if (config3.dialect === "postgres") {
4705
7911
  const q = bunSql`INSERT INTO ${bunSql(String(table))} ${bunSql(values)} RETURNING ${bunSql(String(pk))} as id`;
4706
7912
  const [result] = await q.execute();
4707
7913
  console.log("resultId", result);
@@ -4717,7 +7923,7 @@ function createQueryBuilder(state) {
4717
7923
  throw new Error(`create() failed to retrieve inserted row for table ${String(table)} with id ${result.id}`);
4718
7924
  }
4719
7925
  try {
4720
- await config2.hooks?.afterCreate?.({ table: String(table), data: values, result: row });
7926
+ await config3.hooks?.afterCreate?.({ table: String(table), data: values, result: row });
4721
7927
  } catch {}
4722
7928
  return row;
4723
7929
  } else {
@@ -4732,7 +7938,7 @@ function createQueryBuilder(state) {
4732
7938
  throw new Error(`create() failed to retrieve inserted row for table ${String(table)} with id ${id}`);
4733
7939
  }
4734
7940
  try {
4735
- await config2.hooks?.afterCreate?.({ table: String(table), data: values, result: row });
7941
+ await config3.hooks?.afterCreate?.({ table: String(table), data: values, result: row });
4736
7942
  } catch {}
4737
7943
  return row;
4738
7944
  }
@@ -4995,7 +8201,7 @@ var init_cache = __esm(async () => {
4995
8201
  });
4996
8202
 
4997
8203
  // src/actions/console.ts
4998
- import process9 from "process";
8204
+ import process15 from "process";
4999
8205
  import { createInterface } from "readline";
5000
8206
  async function startConsole() {
5001
8207
  console.log("-- Query Builder Interactive Console");
@@ -5004,8 +8210,8 @@ async function startConsole() {
5004
8210
  console.log();
5005
8211
  const qb = createQueryBuilder();
5006
8212
  const rl = createInterface({
5007
- input: process9.stdin,
5008
- output: process9.stdout,
8213
+ input: process15.stdin,
8214
+ output: process15.stdout,
5009
8215
  prompt: "qb> "
5010
8216
  });
5011
8217
  let multilineBuffer = "";
@@ -5056,7 +8262,7 @@ Tips:
5056
8262
  if (cmd === ".exit" || cmd === ".quit") {
5057
8263
  console.log("Goodbye!");
5058
8264
  rl.close();
5059
- process9.exit(0);
8265
+ process15.exit(0);
5060
8266
  } else if (cmd === ".help") {
5061
8267
  console.log(helpText);
5062
8268
  } else if (cmd === ".clear") {
@@ -5127,7 +8333,7 @@ Tips:
5127
8333
  rl.on("close", () => {
5128
8334
  console.log(`
5129
8335
  Goodbye!`);
5130
- process9.exit(0);
8336
+ process15.exit(0);
5131
8337
  });
5132
8338
  rl.prompt();
5133
8339
  }
@@ -5139,7 +8345,7 @@ var init_console = __esm(async () => {
5139
8345
  });
5140
8346
 
5141
8347
  // src/actions/data.ts
5142
- import { existsSync as existsSync4, readFileSync, writeFileSync as writeFileSync4 } from "fs";
8348
+ import { existsSync as existsSync6, readFileSync, writeFileSync as writeFileSync6 } from "fs";
5143
8349
  async function exportData(tableName, options = {}) {
5144
8350
  const format = options.format || "json";
5145
8351
  const output = options.output || `${tableName}.${format}`;
@@ -5160,11 +8366,11 @@ async function exportData(tableName, options = {}) {
5160
8366
  const data = await query.execute();
5161
8367
  console.log(`-- Retrieved ${data.length} rows`);
5162
8368
  if (format === "json") {
5163
- writeFileSync4(output, JSON.stringify(data, null, 2));
8369
+ writeFileSync6(output, JSON.stringify(data, null, 2));
5164
8370
  console.log(`-- \u2713 Exported to JSON: ${output}`);
5165
8371
  } else if (format === "csv") {
5166
8372
  if (data.length === 0) {
5167
- writeFileSync4(output, "");
8373
+ writeFileSync6(output, "");
5168
8374
  console.log(`-- \u2713 Exported to CSV: ${output} (empty)`);
5169
8375
  return;
5170
8376
  }
@@ -5185,7 +8391,7 @@ async function exportData(tableName, options = {}) {
5185
8391
  });
5186
8392
  csvLines.push(values.join(","));
5187
8393
  }
5188
- writeFileSync4(output, csvLines.join(`
8394
+ writeFileSync6(output, csvLines.join(`
5189
8395
  `));
5190
8396
  console.log(`-- \u2713 Exported to CSV: ${output}`);
5191
8397
  } else if (format === "sql") {
@@ -5204,7 +8410,7 @@ async function exportData(tableName, options = {}) {
5204
8410
  });
5205
8411
  sqlLines.push(`INSERT INTO ${tableName} (${columns.join(", ")}) VALUES (${values.join(", ")});`);
5206
8412
  }
5207
- writeFileSync4(output, sqlLines.join(`
8413
+ writeFileSync6(output, sqlLines.join(`
5208
8414
  `));
5209
8415
  console.log(`-- \u2713 Exported to SQL: ${output}`);
5210
8416
  }
@@ -5214,7 +8420,7 @@ async function exportData(tableName, options = {}) {
5214
8420
  }
5215
8421
  }
5216
8422
  async function importData(tableName, filePath, options = {}) {
5217
- if (!existsSync4(filePath)) {
8423
+ if (!existsSync6(filePath)) {
5218
8424
  console.error(`-- File not found: ${filePath}`);
5219
8425
  throw new Error(`File not found: ${filePath}`);
5220
8426
  }
@@ -5283,7 +8489,7 @@ async function importData(tableName, filePath, options = {}) {
5283
8489
  }
5284
8490
  }
5285
8491
  async function dumpDatabase(options = {}) {
5286
- const dialect = config2.dialect || "postgres";
8492
+ const dialect = config3.dialect || "postgres";
5287
8493
  const output = options.output || `dump-${Date.now()}.sql`;
5288
8494
  const tablesToDump = options.tables?.split(",").map((t) => t.trim());
5289
8495
  console.log("-- Dumping database");
@@ -5358,7 +8564,7 @@ async function dumpDatabase(options = {}) {
5358
8564
  }
5359
8565
  sqlLines.push("");
5360
8566
  }
5361
- writeFileSync4(output, sqlLines.join(`
8567
+ writeFileSync6(output, sqlLines.join(`
5362
8568
  `));
5363
8569
  console.log();
5364
8570
  console.log(`-- \u2713 Database dump saved to: ${output}`);
@@ -5376,8 +8582,8 @@ var init_data = __esm(async () => {
5376
8582
 
5377
8583
  // src/actions/db-info.ts
5378
8584
  async function dbInfo() {
5379
- const dialect = config2.dialect || "postgres";
5380
- const database = config2.database?.database || "unknown";
8585
+ const dialect = config3.dialect || "postgres";
8586
+ const database = config3.database?.database || "unknown";
5381
8587
  console.log("-- Database Information");
5382
8588
  console.log(`-- Dialect: ${dialect}`);
5383
8589
  console.log(`-- Database: ${database}`);
@@ -5508,9 +8714,9 @@ var init_db_info = __esm(async () => {
5508
8714
  });
5509
8715
 
5510
8716
  // src/actions/db-optimize.ts
5511
- import process10 from "process";
8717
+ import process16 from "process";
5512
8718
  async function dbOptimize(options = {}) {
5513
- const dialect = options.dialect || process10.env.DB_DIALECT || "postgres";
8719
+ const dialect = options.dialect || process16.env.DB_DIALECT || "postgres";
5514
8720
  const aggressive = options.aggressive || false;
5515
8721
  if (options.verbose) {
5516
8722
  console.log(`Optimizing ${dialect} database${aggressive ? " (aggressive mode)" : ""}...`);
@@ -5550,7 +8756,7 @@ async function dbOptimize(options = {}) {
5550
8756
  await bunSql`ANALYZE TABLE ${bunSql(table)}`;
5551
8757
  }
5552
8758
  } else {
5553
- const dbName = process10.env.DB_NAME || "test";
8759
+ const dbName = process16.env.DB_NAME || "test";
5554
8760
  const tables = await bunSql`
5555
8761
  SELECT table_name
5556
8762
  FROM information_schema.tables
@@ -5602,9 +8808,9 @@ var init_db_optimize = __esm(async () => {
5602
8808
  });
5603
8809
 
5604
8810
  // src/actions/db-wipe.ts
5605
- import process11 from "process";
8811
+ import process17 from "process";
5606
8812
  async function dbWipe(options = {}) {
5607
- const dialect = options.dialect || process11.env.DB_DIALECT || "postgres";
8813
+ const dialect = options.dialect || process17.env.DB_DIALECT || "postgres";
5608
8814
  if (options.verbose) {
5609
8815
  console.log(`Wiping all tables from ${dialect} database...`);
5610
8816
  }
@@ -5618,7 +8824,7 @@ async function dbWipe(options = {}) {
5618
8824
  `;
5619
8825
  tables = result.map((row) => row.tablename);
5620
8826
  } else if (dialect === "mysql") {
5621
- const dbName = process11.env.DB_NAME || "test";
8827
+ const dbName = process17.env.DB_NAME || "test";
5622
8828
  const result = await bunSql`
5623
8829
  SELECT table_name
5624
8830
  FROM information_schema.tables
@@ -5703,7 +8909,7 @@ var init_file = __esm(async () => {
5703
8909
 
5704
8910
  // src/actions/inspect.ts
5705
8911
  async function inspectTable(tableName, options = {}) {
5706
- const dialect = config2.dialect || "postgres";
8912
+ const dialect = config3.dialect || "postgres";
5707
8913
  const verbose = options.verbose ?? true;
5708
8914
  if (verbose) {
5709
8915
  console.log(`-- Inspecting table: ${tableName}`);
@@ -5912,31 +9118,31 @@ var init_introspect = __esm(async () => {
5912
9118
  });
5913
9119
 
5914
9120
  // 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";
9121
+ import { existsSync as existsSync9, mkdirSync as mkdirSync4, writeFileSync as writeFileSync8 } from "fs";
9122
+ import { dirname as dirname4, join as join4 } from "path";
9123
+ import process18 from "process";
5918
9124
  function findWorkspaceRoot(startPath) {
5919
9125
  let currentPath = startPath;
5920
- while (currentPath !== dirname3(currentPath)) {
5921
- if (existsSync6(join3(currentPath, "package.json"))) {
9126
+ while (currentPath !== dirname4(currentPath)) {
9127
+ if (existsSync9(join4(currentPath, "package.json"))) {
5922
9128
  return currentPath;
5923
9129
  }
5924
- currentPath = dirname3(currentPath);
9130
+ currentPath = dirname4(currentPath);
5925
9131
  }
5926
- return process12.cwd();
9132
+ return process18.cwd();
5927
9133
  }
5928
9134
  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 });
9135
+ const workspaceRoot = findWorkspaceRoot(process18.cwd());
9136
+ const modelsDir = options.dir || join4(workspaceRoot, "app/Models");
9137
+ if (!existsSync9(modelsDir)) {
9138
+ mkdirSync4(modelsDir, { recursive: true });
5933
9139
  console.log(`-- Created models directory: ${modelsDir}`);
5934
9140
  }
5935
9141
  const className = name.charAt(0).toUpperCase() + name.slice(1);
5936
9142
  const tableName = options.table || `${name.toLowerCase()}s`;
5937
9143
  const fileName = `${className}.ts`;
5938
- const filePath = join3(modelsDir, fileName);
5939
- if (existsSync6(filePath)) {
9144
+ const filePath = join4(modelsDir, fileName);
9145
+ if (existsSync9(filePath)) {
5940
9146
  console.error(`-- Model already exists: ${filePath}`);
5941
9147
  throw new Error(`Model already exists: ${filePath}`);
5942
9148
  }
@@ -5963,7 +9169,7 @@ ${timestampFields}
5963
9169
 
5964
9170
  export default model
5965
9171
  `;
5966
- writeFileSync6(filePath, template);
9172
+ writeFileSync8(filePath, template);
5967
9173
  console.log(`-- \u2713 Created model: ${filePath}`);
5968
9174
  console.log(`-- Table: ${tableName}`);
5969
9175
  }
@@ -6441,42 +9647,42 @@ __export(exports_migrate, {
6441
9647
  deleteMigrationFiles: () => deleteMigrationFiles,
6442
9648
  copyModelsToGenerated: () => copyModelsToGenerated
6443
9649
  });
6444
- import { copyFileSync, existsSync as existsSync7, mkdirSync as mkdirSync5, mkdtempSync, readdirSync as readdirSync3, readFileSync as readFileSync2, unlinkSync, writeFileSync as writeFileSync7 } from "fs";
9650
+ import { copyFileSync, existsSync as existsSync11, mkdirSync as mkdirSync6, mkdtempSync, readdirSync as readdirSync4, readFileSync as readFileSync2, unlinkSync, writeFileSync as writeFileSync9 } from "fs";
6445
9651
  import { tmpdir } from "os";
6446
- import { join as join5 } from "path";
6447
- import process13 from "process";
9652
+ import { join as join6 } from "path";
9653
+ import process19 from "process";
6448
9654
  function getWorkspaceRoot() {
6449
- return process13.cwd();
9655
+ return process19.cwd();
6450
9656
  }
6451
9657
  function ensureSqlDirectory(workspaceRoot) {
6452
9658
  const sqlDir = getSqlDirectory(workspaceRoot);
6453
- if (!existsSync7(sqlDir)) {
6454
- mkdirSync5(sqlDir, { recursive: true });
9659
+ if (!existsSync11(sqlDir)) {
9660
+ mkdirSync6(sqlDir, { recursive: true });
6455
9661
  console.log(`-- Created SQL directory: ${sqlDir}`);
6456
9662
  }
6457
9663
  return sqlDir;
6458
9664
  }
6459
9665
  async function generateMigration(dir, opts = {}) {
6460
9666
  if (!dir) {
6461
- dir = join5(process13.cwd(), "app/Models");
9667
+ dir = join6(process19.cwd(), "app/Models");
6462
9668
  }
6463
- const dialect = opts.dialect || config2.dialect || "postgres";
9669
+ const dialect = opts.dialect || config3.dialect || "postgres";
6464
9670
  const workspaceRoot = getWorkspaceRoot();
6465
9671
  const models = await loadModels({ modelsDir: dir });
6466
9672
  const plan = buildMigrationPlan(models, { dialect });
6467
- const defaultStatePath = join5(dir, `.qb-migrations.${dialect}.json`);
9673
+ const defaultStatePath = join6(dir, `.qb-migrations.${dialect}.json`);
6468
9674
  const statePath = String(opts.state || defaultStatePath);
6469
9675
  let previous;
6470
9676
  if (!opts.full) {
6471
- const generatedDir = join5(workspaceRoot, "generated");
6472
- if (existsSync7(generatedDir)) {
9677
+ const generatedDir = join6(workspaceRoot, "generated");
9678
+ if (existsSync11(generatedDir)) {
6473
9679
  try {
6474
9680
  const oldModels = await loadModels({ modelsDir: generatedDir });
6475
9681
  previous = buildMigrationPlan(oldModels, { dialect });
6476
9682
  console.log("-- Comparing with models from generated/ directory");
6477
9683
  } catch (err) {
6478
9684
  console.log("-- No previous models found in generated/ directory, checking state file", err);
6479
- if (existsSync7(statePath)) {
9685
+ if (existsSync11(statePath)) {
6480
9686
  try {
6481
9687
  const raw = readFileSync2(statePath, "utf8");
6482
9688
  const parsed = JSON.parse(raw);
@@ -6484,7 +9690,7 @@ async function generateMigration(dir, opts = {}) {
6484
9690
  } catch {}
6485
9691
  }
6486
9692
  }
6487
- } else if (existsSync7(statePath)) {
9693
+ } else if (existsSync11(statePath)) {
6488
9694
  try {
6489
9695
  const raw = readFileSync2(statePath, "utf8");
6490
9696
  const parsed = JSON.parse(raw);
@@ -6497,16 +9703,16 @@ async function generateMigration(dir, opts = {}) {
6497
9703
  `);
6498
9704
  const hasChanges = sqlStatements.some((stmt) => /\b(?:CREATE|ALTER)\b/i.test(stmt));
6499
9705
  if (opts.apply) {
6500
- const dirPath = mkdtempSync(join5(tmpdir(), "qb-migrate-"));
6501
- const filePath = join5(dirPath, "migration.sql");
9706
+ const dirPath = mkdtempSync(join6(tmpdir(), "qb-migrate-"));
9707
+ const filePath = join6(dirPath, "migration.sql");
6502
9708
  try {
6503
9709
  if (hasChanges) {
6504
- writeFileSync7(filePath, sql);
9710
+ writeFileSync9(filePath, sql);
6505
9711
  console.log("-- Migration applied");
6506
9712
  } else {
6507
9713
  console.log("-- No changes; nothing to apply");
6508
9714
  }
6509
- writeFileSync7(statePath, JSON.stringify({ plan, hash: hashMigrationPlan(plan), updatedAt: new Date().toISOString() }, null, 2));
9715
+ writeFileSync9(statePath, JSON.stringify({ plan, hash: hashMigrationPlan(plan), updatedAt: new Date().toISOString() }, null, 2));
6510
9716
  } catch (err) {
6511
9717
  console.error("-- Migration failed:", err);
6512
9718
  throw err;
@@ -6517,12 +9723,12 @@ async function generateMigration(dir, opts = {}) {
6517
9723
  }
6518
9724
  async function executeMigration(dir) {
6519
9725
  if (!dir) {
6520
- dir = join5(process13.cwd(), "app/Models");
9726
+ dir = join6(process19.cwd(), "app/Models");
6521
9727
  }
6522
9728
  const workspaceRoot = getWorkspaceRoot();
6523
9729
  const sqlDir = ensureSqlDirectory(workspaceRoot);
6524
- const dialect = config2.dialect || "postgres";
6525
- const files = readdirSync3(sqlDir);
9730
+ const dialect = config3.dialect || "postgres";
9731
+ const files = readdirSync4(sqlDir);
6526
9732
  const scriptFiles = files.filter((file2) => file2.endsWith(".sql")).sort();
6527
9733
  if (scriptFiles.length === 0) {
6528
9734
  console.log("-- No migration files found to execute");
@@ -6549,7 +9755,7 @@ async function executeMigration(dir) {
6549
9755
  }
6550
9756
  console.log(`-- Executing ${totalPending} migrations (${permanentMigrations.length} permanent, ${transientMigrations.length} transient)`);
6551
9757
  for (const file2 of permanentMigrations) {
6552
- const filePath = join5(sqlDir, file2);
9758
+ const filePath = join6(sqlDir, file2);
6553
9759
  console.log(`-- Executing: ${file2}`);
6554
9760
  try {
6555
9761
  await qb.file(filePath);
@@ -6561,7 +9767,7 @@ async function executeMigration(dir) {
6561
9767
  }
6562
9768
  }
6563
9769
  for (const file2 of transientMigrations) {
6564
- const filePath = join5(sqlDir, file2);
9770
+ const filePath = join6(sqlDir, file2);
6565
9771
  console.log(`-- Executing: ${file2} (transient)`);
6566
9772
  try {
6567
9773
  await qb.file(filePath);
@@ -6582,7 +9788,7 @@ async function executeMigration(dir) {
6582
9788
  }
6583
9789
  async function resetDatabase(dir, opts = {}) {
6584
9790
  if (!dir) {
6585
- dir = join5(process13.cwd(), "app/Models");
9791
+ dir = join6(process19.cwd(), "app/Models");
6586
9792
  }
6587
9793
  const dialect = opts.dialect || "postgres";
6588
9794
  const driver = getDialectDriver(dialect);
@@ -6669,24 +9875,24 @@ async function resetDatabase(dir, opts = {}) {
6669
9875
  }
6670
9876
  async function deleteMigrationFiles(dir, workspaceRoot, opts = {}) {
6671
9877
  if (!dir) {
6672
- dir = join5(process13.cwd(), "app/Models");
9878
+ dir = join6(process19.cwd(), "app/Models");
6673
9879
  }
6674
9880
  if (!workspaceRoot) {
6675
9881
  workspaceRoot = getWorkspaceRoot();
6676
9882
  }
6677
9883
  const dialect = String(opts.dialect || "postgres");
6678
- const defaultStatePath = join5(dir, `.qb-migrations.${dialect}.json`);
9884
+ const defaultStatePath = join6(dir, `.qb-migrations.${dialect}.json`);
6679
9885
  const statePath = String(opts.state || defaultStatePath);
6680
- if (existsSync7(statePath)) {
9886
+ if (existsSync11(statePath)) {
6681
9887
  unlinkSync(statePath);
6682
9888
  console.log(`-- Removed migration state file: ${statePath}`);
6683
9889
  }
6684
9890
  const sqlDir = getSqlDirectory(workspaceRoot);
6685
- if (existsSync7(sqlDir)) {
6686
- const sqlFiles = readdirSync3(sqlDir);
9891
+ if (existsSync11(sqlDir)) {
9892
+ const sqlFiles = readdirSync4(sqlDir);
6687
9893
  const migrationFiles = sqlFiles.filter((file2) => file2.endsWith(".sql"));
6688
9894
  for (const file2 of migrationFiles) {
6689
- const filePath = join5(sqlDir, file2);
9895
+ const filePath = join6(sqlDir, file2);
6690
9896
  unlinkSync(filePath);
6691
9897
  console.log(`-- Removed migration file: ${file2}`);
6692
9898
  }
@@ -6695,26 +9901,26 @@ async function deleteMigrationFiles(dir, workspaceRoot, opts = {}) {
6695
9901
  }
6696
9902
  async function copyModelsToGenerated(dir, workspaceRoot) {
6697
9903
  if (!dir) {
6698
- dir = join5(process13.cwd(), "app/Models");
9904
+ dir = join6(process19.cwd(), "app/Models");
6699
9905
  }
6700
9906
  if (!workspaceRoot) {
6701
9907
  workspaceRoot = getWorkspaceRoot();
6702
9908
  }
6703
9909
  try {
6704
- const generatedDir = join5(workspaceRoot, "generated");
6705
- if (!existsSync7(generatedDir)) {
6706
- mkdirSync5(generatedDir, { recursive: true });
9910
+ const generatedDir = join6(workspaceRoot, "generated");
9911
+ if (!existsSync11(generatedDir)) {
9912
+ mkdirSync6(generatedDir, { recursive: true });
6707
9913
  console.log("-- Created generated directory");
6708
9914
  }
6709
- const files = readdirSync3(dir);
9915
+ const files = readdirSync4(dir);
6710
9916
  const modelFiles = files.filter((file2) => file2.endsWith(".ts") || file2.endsWith(".js"));
6711
9917
  if (modelFiles.length === 0) {
6712
9918
  console.log("-- No model files found to copy");
6713
9919
  return;
6714
9920
  }
6715
9921
  for (const file2 of modelFiles) {
6716
- const sourcePath = join5(dir, file2);
6717
- const destPath = join5(generatedDir, file2);
9922
+ const sourcePath = join6(dir, file2);
9923
+ const destPath = join6(generatedDir, file2);
6718
9924
  copyFileSync(sourcePath, destPath);
6719
9925
  }
6720
9926
  console.log("-- Model files copied successfully");
@@ -6727,7 +9933,7 @@ function getSqlDirectory(workspaceRoot) {
6727
9933
  if (!workspaceRoot) {
6728
9934
  workspaceRoot = getWorkspaceRoot();
6729
9935
  }
6730
- return join5(workspaceRoot, "database", "sql");
9936
+ return join6(workspaceRoot, "database", "sql");
6731
9937
  }
6732
9938
  async function createMigrationsTable(qb, dialect) {
6733
9939
  const driver = getDialectDriver(dialect);
@@ -6779,24 +9985,24 @@ var init_migrate_generate = __esm(async () => {
6779
9985
  });
6780
9986
 
6781
9987
  // 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";
9988
+ import { existsSync as existsSync12, unlinkSync as unlinkSync2 } from "fs";
9989
+ import { dirname as dirname6, join as join7 } from "path";
9990
+ import process20 from "process";
6785
9991
  function findWorkspaceRoot2(startPath) {
6786
9992
  let currentPath = startPath;
6787
- while (currentPath !== dirname5(currentPath)) {
6788
- if (existsSync8(join6(currentPath, "package.json"))) {
9993
+ while (currentPath !== dirname6(currentPath)) {
9994
+ if (existsSync12(join7(currentPath, "package.json"))) {
6789
9995
  return currentPath;
6790
9996
  }
6791
- currentPath = dirname5(currentPath);
9997
+ currentPath = dirname6(currentPath);
6792
9998
  }
6793
- return process14.cwd();
9999
+ return process20.cwd();
6794
10000
  }
6795
10001
  function getSqlDirectory2(workspaceRoot) {
6796
10002
  if (!workspaceRoot) {
6797
- workspaceRoot = findWorkspaceRoot2(process14.cwd());
10003
+ workspaceRoot = findWorkspaceRoot2(process20.cwd());
6798
10004
  }
6799
- return join6(workspaceRoot, "sql");
10005
+ return join7(workspaceRoot, "sql");
6800
10006
  }
6801
10007
  async function migrateRollback(options = {}) {
6802
10008
  const steps = options.steps || 1;
@@ -6835,8 +10041,8 @@ async function migrateRollback(options = {}) {
6835
10041
  await qb.unsafe(deleteSql, [migration.migration]);
6836
10042
  console.log(`-- \u2713 Removed migration record: ${migration.migration}`);
6837
10043
  const sqlDir = getSqlDirectory2();
6838
- const filePath = join6(sqlDir, migration.migration);
6839
- if (existsSync8(filePath)) {
10044
+ const filePath = join7(sqlDir, migration.migration);
10045
+ if (existsSync12(filePath)) {
6840
10046
  unlinkSync2(filePath);
6841
10047
  console.log(`-- \uD83D\uDDD1\uFE0F Deleted migration file: ${migration.migration}`);
6842
10048
  }
@@ -6861,38 +10067,38 @@ var init_migrate_rollback = __esm(async () => {
6861
10067
  });
6862
10068
 
6863
10069
  // 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";
10070
+ import { existsSync as existsSync13, readdirSync as readdirSync6 } from "fs";
10071
+ import { dirname as dirname7, join as join8 } from "path";
10072
+ import process21 from "process";
6867
10073
  function findWorkspaceRoot3(startPath) {
6868
10074
  let currentPath = startPath;
6869
- while (currentPath !== dirname6(currentPath)) {
6870
- if (existsSync9(join7(currentPath, "package.json"))) {
10075
+ while (currentPath !== dirname7(currentPath)) {
10076
+ if (existsSync13(join8(currentPath, "package.json"))) {
6871
10077
  return currentPath;
6872
10078
  }
6873
- currentPath = dirname6(currentPath);
10079
+ currentPath = dirname7(currentPath);
6874
10080
  }
6875
- return process15.cwd();
10081
+ return process21.cwd();
6876
10082
  }
6877
10083
  function getSqlDirectory3(workspaceRoot) {
6878
10084
  if (!workspaceRoot) {
6879
- workspaceRoot = findWorkspaceRoot3(process15.cwd());
10085
+ workspaceRoot = findWorkspaceRoot3(process21.cwd());
6880
10086
  }
6881
- return join7(workspaceRoot, "sql");
10087
+ return join8(workspaceRoot, "sql");
6882
10088
  }
6883
10089
  async function migrateStatus() {
6884
- const dialect = config2.dialect || "postgres";
10090
+ const dialect = config3.dialect || "postgres";
6885
10091
  const driver = getDialectDriver(dialect);
6886
10092
  const sqlDir = getSqlDirectory3();
6887
10093
  console.log("-- Migration Status");
6888
10094
  console.log(`-- Dialect: ${dialect}`);
6889
10095
  console.log(`-- SQL directory: ${sqlDir}`);
6890
10096
  console.log();
6891
- if (!existsSync9(sqlDir)) {
10097
+ if (!existsSync13(sqlDir)) {
6892
10098
  console.log("-- No SQL directory found. No migrations have been created yet.");
6893
10099
  return [];
6894
10100
  }
6895
- const files = readdirSync5(sqlDir);
10101
+ const files = readdirSync6(sqlDir);
6896
10102
  const migrationFiles = files.filter((file2) => file2.endsWith(".sql")).sort();
6897
10103
  if (migrationFiles.length === 0) {
6898
10104
  console.log("-- No migration files found");
@@ -6970,13 +10176,13 @@ var init_migrate_status = __esm(async () => {
6970
10176
  });
6971
10177
 
6972
10178
  // 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";
10179
+ import { readdirSync as readdirSync7 } from "fs";
10180
+ import { extname, join as join9 } from "path";
10181
+ import process22 from "process";
6976
10182
  async function modelShow(modelName, options = {}) {
6977
- const dir = options.dir || join8(process16.cwd(), "app/Models");
10183
+ const dir = options.dir || join9(process22.cwd(), "app/Models");
6978
10184
  try {
6979
- const files = readdirSync6(dir);
10185
+ const files = readdirSync7(dir);
6980
10186
  const modelFile = files.find((f) => {
6981
10187
  const name = f.replace(extname(f), "");
6982
10188
  return name.toLowerCase() === modelName.toLowerCase();
@@ -6986,7 +10192,7 @@ async function modelShow(modelName, options = {}) {
6986
10192
  console.log(`Available models: ${files.filter((f) => [".ts", ".js"].includes(extname(f))).map((f) => f.replace(extname(f), "")).join(", ")}`);
6987
10193
  return;
6988
10194
  }
6989
- const modelPath = join8(dir, modelFile);
10195
+ const modelPath = join9(dir, modelFile);
6990
10196
  const module = await import(modelPath);
6991
10197
  const model = module.default || module[Object.keys(module)[0]];
6992
10198
  if (!model || !model.name) {
@@ -7093,17 +10299,17 @@ var init_ping = __esm(async () => {
7093
10299
  });
7094
10300
 
7095
10301
  // 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";
10302
+ import { readdirSync as readdirSync8, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
10303
+ import { extname as extname2, join as join10 } from "path";
7098
10304
  async function queryExplainAll(path, options = {}) {
7099
10305
  const results = [];
7100
10306
  try {
7101
- const stat2 = statSync(path);
10307
+ const stat3 = statSync2(path);
7102
10308
  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") {
10309
+ if (stat3.isDirectory()) {
10310
+ const allFiles = readdirSync8(path);
10311
+ files = allFiles.filter((f) => extname2(f) === ".sql").map((f) => join10(path, f));
10312
+ } else if (stat3.isFile() && extname2(path) === ".sql") {
7107
10313
  files = [path];
7108
10314
  } else {
7109
10315
  console.error("Path must be a .sql file or directory containing .sql files");
@@ -7186,11 +10392,11 @@ var init_query_explain_all = __esm(async () => {
7186
10392
  });
7187
10393
 
7188
10394
  // src/actions/relation-diagram.ts
7189
- import { writeFileSync as writeFileSync8 } from "fs";
7190
- import { join as join10 } from "path";
7191
- import process17 from "process";
10395
+ import { writeFileSync as writeFileSync10 } from "fs";
10396
+ import { join as join11 } from "path";
10397
+ import process23 from "process";
7192
10398
  async function relationDiagram(options = {}) {
7193
- const dir = options.dir || join10(process17.cwd(), "app/Models");
10399
+ const dir = options.dir || join11(process23.cwd(), "app/Models");
7194
10400
  const format = options.format || "mermaid";
7195
10401
  try {
7196
10402
  const models = await loadModels({ modelsDir: dir });
@@ -7208,7 +10414,7 @@ async function relationDiagram(options = {}) {
7208
10414
  return "";
7209
10415
  }
7210
10416
  if (options.output) {
7211
- writeFileSync8(options.output, diagram, "utf8");
10417
+ writeFileSync10(options.output, diagram, "utf8");
7212
10418
  console.log(`\u2713 Diagram written to: ${options.output}`);
7213
10419
  } else {
7214
10420
  console.log(diagram);
@@ -7310,29 +10516,29 @@ var init_relation_diagram = __esm(async () => {
7310
10516
  });
7311
10517
 
7312
10518
  // 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";
10519
+ import { existsSync as existsSync14, mkdirSync as mkdirSync7, readdirSync as readdirSync9, writeFileSync as writeFileSync11 } from "fs";
10520
+ import { dirname as dirname8, join as join12 } from "path";
10521
+ import process24 from "process";
7316
10522
  function findWorkspaceRoot4(startPath) {
7317
10523
  let currentPath = startPath;
7318
- while (currentPath !== dirname7(currentPath)) {
7319
- if (existsSync10(join11(currentPath, "package.json"))) {
10524
+ while (currentPath !== dirname8(currentPath)) {
10525
+ if (existsSync14(join12(currentPath, "package.json"))) {
7320
10526
  return currentPath;
7321
10527
  }
7322
- currentPath = dirname7(currentPath);
10528
+ currentPath = dirname8(currentPath);
7323
10529
  }
7324
- return process18.cwd();
10530
+ return process24.cwd();
7325
10531
  }
7326
10532
  async function loadSeeders(seedersDir) {
7327
- if (!existsSync10(seedersDir)) {
10533
+ if (!existsSync14(seedersDir)) {
7328
10534
  console.log(`-- Seeders directory not found: ${seedersDir}`);
7329
10535
  return [];
7330
10536
  }
7331
- const files = readdirSync8(seedersDir);
10537
+ const files = readdirSync9(seedersDir);
7332
10538
  const seederFiles = files.filter((file2) => (file2.endsWith(".ts") || file2.endsWith(".js")) && file2 !== "index.ts" && file2 !== "index.js");
7333
10539
  const seeders = [];
7334
10540
  for (const file2 of seederFiles) {
7335
- const filePath = join11(seedersDir, file2);
10541
+ const filePath = join12(seedersDir, file2);
7336
10542
  try {
7337
10543
  const module = await import(filePath);
7338
10544
  const SeederClass = module.default || module[Object.keys(module)[0]];
@@ -7352,10 +10558,10 @@ async function loadSeeders(seedersDir) {
7352
10558
  seeders.sort((a, b) => a.instance.order - b.instance.order);
7353
10559
  return seeders;
7354
10560
  }
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;
10561
+ async function runSeeders(config4 = {}) {
10562
+ const workspaceRoot = findWorkspaceRoot4(process24.cwd());
10563
+ const seedersDir = config4.seedersDir || join12(workspaceRoot, "database/seeders");
10564
+ const verbose = config4.verbose ?? true;
7359
10565
  if (verbose) {
7360
10566
  console.log("-- Running seeders...");
7361
10567
  console.log(`-- Seeders directory: ${seedersDir}`);
@@ -7388,8 +10594,8 @@ async function runSeeders(config3 = {}) {
7388
10594
  }
7389
10595
  }
7390
10596
  async function runSeeder(className, options = {}) {
7391
- const workspaceRoot = findWorkspaceRoot4(process18.cwd());
7392
- const seedersDir = join11(workspaceRoot, "database/seeders");
10597
+ const workspaceRoot = findWorkspaceRoot4(process24.cwd());
10598
+ const seedersDir = join12(workspaceRoot, "database/seeders");
7393
10599
  const verbose = options.verbose ?? true;
7394
10600
  if (verbose) {
7395
10601
  console.log(`-- Running seeder: ${className}`);
@@ -7412,17 +10618,17 @@ async function runSeeder(className, options = {}) {
7412
10618
  }
7413
10619
  }
7414
10620
  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 });
10621
+ const workspaceRoot = findWorkspaceRoot4(process24.cwd());
10622
+ const seedersDir = join12(workspaceRoot, "database/seeders");
10623
+ if (!existsSync14(seedersDir)) {
10624
+ mkdirSync7(seedersDir, { recursive: true });
7419
10625
  console.log(`-- Created seeders directory: ${seedersDir}`);
7420
10626
  }
7421
10627
  const baseName = name.replace(/Seeder$/i, "");
7422
10628
  const className = `${baseName}Seeder`;
7423
10629
  const fileName = `${className}.ts`;
7424
- const filePath = join11(seedersDir, fileName);
7425
- if (existsSync10(filePath)) {
10630
+ const filePath = join12(seedersDir, fileName);
10631
+ if (existsSync14(filePath)) {
7426
10632
  console.error(`-- Seeder already exists: ${filePath}`);
7427
10633
  throw new Error(`Seeder already exists: ${filePath}`);
7428
10634
  }
@@ -7472,13 +10678,13 @@ export default class ${className} extends Seeder {
7472
10678
  }
7473
10679
  }
7474
10680
  `;
7475
- writeFileSync9(filePath, template);
10681
+ writeFileSync11(filePath, template);
7476
10682
  console.log(`-- \u2713 Created seeder: ${filePath}`);
7477
10683
  }
7478
10684
  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");
10685
+ const workspaceRoot = findWorkspaceRoot4(process24.cwd());
10686
+ const modelsDir = options.modelsDir || join12(workspaceRoot, "app/Models");
10687
+ const seedersDir = options.seedersDir || join12(workspaceRoot, "database/seeders");
7482
10688
  const verbose = options.verbose ?? true;
7483
10689
  try {
7484
10690
  const { resetDatabase: resetDatabase2, generateMigration: generateMigration2, executeMigration: executeMigration2 } = await init_migrate().then(() => exports_migrate);
@@ -7511,8 +10717,8 @@ var init_seed = __esm(async () => {
7511
10717
  function sql(dir, table, opts = {}) {
7512
10718
  const models = loadModels({ modelsDir: dir });
7513
10719
  const dbSchema = buildDatabaseSchema(models);
7514
- if (config2.debug)
7515
- config2.debug.captureText = true;
10720
+ if (config3.debug)
10721
+ config3.debug.captureText = true;
7516
10722
  const qb = createQueryBuilder({ schema: dbSchema });
7517
10723
  const s = qb.selectFrom(table).limit(Number(opts.limit || 10)).toText?.() ?? "";
7518
10724
  console.log(s || "[query]");
@@ -7538,24 +10744,24 @@ var init_unsafe = __esm(async () => {
7538
10744
  });
7539
10745
 
7540
10746
  // 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";
10747
+ import { existsSync as existsSync15 } from "fs";
10748
+ import { dirname as dirname9, join as join13 } from "path";
10749
+ import process25 from "process";
7544
10750
  function findWorkspaceRoot5(startPath) {
7545
10751
  let currentPath = startPath;
7546
- while (currentPath !== dirname8(currentPath)) {
7547
- if (existsSync11(join12(currentPath, "package.json"))) {
10752
+ while (currentPath !== dirname9(currentPath)) {
10753
+ if (existsSync15(join13(currentPath, "package.json"))) {
7548
10754
  return currentPath;
7549
10755
  }
7550
- currentPath = dirname8(currentPath);
10756
+ currentPath = dirname9(currentPath);
7551
10757
  }
7552
- return process19.cwd();
10758
+ return process25.cwd();
7553
10759
  }
7554
10760
  async function validateSchema(dir) {
7555
10761
  if (!dir) {
7556
- dir = join12(findWorkspaceRoot5(process19.cwd()), "app/Models");
10762
+ dir = join13(findWorkspaceRoot5(process25.cwd()), "app/Models");
7557
10763
  }
7558
- const dialect = config2.dialect || "postgres";
10764
+ const dialect = config3.dialect || "postgres";
7559
10765
  console.log("-- Validating Schema");
7560
10766
  console.log(`-- Models directory: ${dir}`);
7561
10767
  console.log(`-- Dialect: ${dialect}`);
@@ -7811,17 +11017,17 @@ function buildDatabaseSchema(models) {
7811
11017
  }
7812
11018
 
7813
11019
  // src/loader.ts
7814
- import { readdirSync as readdirSync9, statSync as statSync2 } from "fs";
11020
+ import { readdirSync as readdirSync10, statSync as statSync3 } from "fs";
7815
11021
  import { basename, extname as extname3 } from "path";
7816
- import process20 from "process";
11022
+ import process26 from "process";
7817
11023
  async function loadModels(options) {
7818
- const cwd = options.cwd ?? process20.cwd();
11024
+ const cwd = options.cwd ?? process26.cwd();
7819
11025
  const dir = options.modelsDir.startsWith("/") ? options.modelsDir : `${cwd}/${options.modelsDir}`;
7820
11026
  const result = {};
7821
- const entries = readdirSync9(dir);
11027
+ const entries = readdirSync10(dir);
7822
11028
  for (const entry of entries) {
7823
11029
  const full = `${dir}/${entry}`;
7824
- const st = statSync2(full);
11030
+ const st = statSync3(full);
7825
11031
  if (st.isDirectory())
7826
11032
  continue;
7827
11033
  const ext = extname3(full);
@@ -7895,24 +11101,24 @@ function buildSchemaMeta(models) {
7895
11101
  }
7896
11102
 
7897
11103
  // 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";
11104
+ import { existsSync as existsSync16, mkdirSync as mkdirSync8, writeFileSync as writeFileSync12 } from "fs";
11105
+ import { dirname as dirname10, join as join14 } from "path";
11106
+ import process27 from "process";
7901
11107
  function findWorkspaceRoot6(startPath) {
7902
11108
  let currentPath = startPath;
7903
- while (currentPath !== dirname9(currentPath)) {
7904
- if (existsSync12(join13(currentPath, "package.json"))) {
11109
+ while (currentPath !== dirname10(currentPath)) {
11110
+ if (existsSync16(join14(currentPath, "package.json"))) {
7905
11111
  return currentPath;
7906
11112
  }
7907
- currentPath = dirname9(currentPath);
11113
+ currentPath = dirname10(currentPath);
7908
11114
  }
7909
- return process21.cwd();
11115
+ return process27.cwd();
7910
11116
  }
7911
11117
  function ensureSqlDirectory2() {
7912
- const workspaceRoot = findWorkspaceRoot6(process21.cwd());
7913
- const sqlDir = join13(workspaceRoot, "database", "sql");
7914
- if (!existsSync12(sqlDir)) {
7915
- mkdirSync7(sqlDir, { recursive: true });
11118
+ const workspaceRoot = findWorkspaceRoot6(process27.cwd());
11119
+ const sqlDir = join14(workspaceRoot, "database", "sql");
11120
+ if (!existsSync16(sqlDir)) {
11121
+ mkdirSync8(sqlDir, { recursive: true });
7916
11122
  console.log(`-- Created SQL directory: ${sqlDir}`);
7917
11123
  }
7918
11124
  return sqlDir;
@@ -7925,8 +11131,8 @@ function createMigrationFile(statement, fileName) {
7925
11131
  const timestamp = baseTimestamp + migrationCounter;
7926
11132
  migrationCounter++;
7927
11133
  const fullFileName = `${timestamp}-${fileName}.sql`;
7928
- const filePath = join13(sqlDir, fullFileName);
7929
- writeFileSync10(filePath, statement);
11134
+ const filePath = join14(sqlDir, fullFileName);
11135
+ writeFileSync12(filePath, statement);
7930
11136
  console.log(`-- Migration file created: ${fullFileName}`);
7931
11137
  migrationsCreatedCount++;
7932
11138
  return true;
@@ -8487,13 +11693,13 @@ export {
8487
11693
  defineSeeder,
8488
11694
  defineModels,
8489
11695
  defineModel,
8490
- defaultConfig2 as defaultConfig,
11696
+ defaultConfig3 as defaultConfig,
8491
11697
  dbWipe,
8492
11698
  dbStats,
8493
11699
  dbOptimize,
8494
11700
  dbInfo,
8495
11701
  createQueryBuilder,
8496
- config2 as config,
11702
+ config3 as config,
8497
11703
  clearQueryCache,
8498
11704
  checkSchema,
8499
11705
  cacheStats,