| 254 | provider, |
| 255 | baseUrl: baseUrl?.trim() || undefined, |
| 256 | modelId: modelId?.trim() || undefined, |
| 257 | apiProtocol, |
| 258 | reasoning, |
| 259 | }; |
| 260 | } |
| 261 | |
| 262 | export class ConfigManager { |
| 263 | private static instance: ConfigManager; |
| 264 | private configData: DataConfig = {}; |
| 265 | private fileConfigData: DataConfig = {}; |
| 266 | private configPath: string = ""; |
| 267 | |
| 268 | private constructor() {} |
| 269 | |
| 270 | public static getInstance(): ConfigManager { |
| 271 | if (!ConfigManager.instance) { |
| 272 | ConfigManager.instance = new ConfigManager(); |
| 273 | } |
| 274 | return ConfigManager.instance; |
| 275 | } |
| 276 | |
| 277 | public load(rootDir: string): DataConfig { |
| 278 | this.configPath = path.join(rootDir, "data", "config.json"); |
| 279 | this.configData = {}; |
| 280 | this.fileConfigData = {}; |
| 281 | if (fs.existsSync(this.configPath)) { |
| 282 | try { |
| 283 | const parsed = JSON.parse(fs.readFileSync(this.configPath, "utf-8")) as unknown; |
| 284 | if ( |
| 285 | parsed && |
| 286 | typeof parsed === "object" && |
| 287 | "scheduledJobs" in (parsed as Record<string, unknown>) |
| 288 | ) { |
| 289 | console.warn( |
| 290 | ' Warning: data/config.json contains deprecated "scheduledJobs". Move them to job.json at the pack root; the old field is ignored.', |
| 291 | ); |
| 292 | } |
| 293 | this.fileConfigData = normalizeDataConfig(parsed); |
| 294 | console.log(" Loaded config from data/config.json"); |
| 295 | } catch (err) { |
| 296 | console.warn(" Warning: Failed to parse data/config.json:", err); |
| 297 | } |
| 298 | } |
| 299 | this.configData = resolveRuntimeConfig(this.fileConfigData); |
| 300 | return this.configData; |
| 301 | } |
| 302 | |
| 303 | public getConfig(): DataConfig { |
| 304 | return this.configData; |
| 305 | } |
| 306 | |
| 307 | public save(rootDir: string, updates: Partial<DataConfig>): void { |
| 308 | const configDir = path.join(rootDir, "data"); |
| 309 | if (!this.configPath) { |
| 310 | this.configPath = path.join(rootDir, "data", "config.json"); |
| 311 | } |
| 312 | if (!fs.existsSync(configDir)) { |
| 313 | fs.mkdirSync(configDir, { recursive: true }); |
nothing calls this directly
no outgoing calls
no test coverage detected