| 284 | } |
| 285 | |
| 286 | async loadSpec(specId: string): Promise<OpenAPIV3.Document> { |
| 287 | this.logger.debug({ specId }, "Loading specification"); |
| 288 | |
| 289 | // Check cache first |
| 290 | const cached = this.specCache.get(specId); |
| 291 | if (cached) { |
| 292 | this.logger.debug({ specId }, "Returning cached specification"); |
| 293 | return cached; |
| 294 | } |
| 295 | |
| 296 | try { |
| 297 | const specPath = path.join(this.dereferencedPath, `${specId}.json`); |
| 298 | const spec = JSON.parse(await fs.readFile(specPath, "utf-8")); |
| 299 | |
| 300 | // Cache the loaded spec |
| 301 | this.specCache.set(specId, spec); |
| 302 | this.logger.info({ specId }, "Successfully loaded specification"); |
| 303 | |
| 304 | return spec; |
| 305 | } catch (error) { |
| 306 | this.logger.error({ specId, error }, "Failed to load specification"); |
| 307 | if ((error as NodeJS.ErrnoException).code === "ENOENT") { |
| 308 | throw new SpecServiceError( |
| 309 | `Specification not found: ${specId}`, |
| 310 | "LOAD_ERROR" |
| 311 | ); |
| 312 | } |
| 313 | throw new SpecServiceError( |
| 314 | `Failed to load specification ${specId}`, |
| 315 | "LOAD_ERROR", |
| 316 | error instanceof Error ? error : new Error(String(error)) |
| 317 | ); |
| 318 | } |
| 319 | } |
| 320 | |
| 321 | public async refresh(): Promise<void> { |
| 322 | if (!this.folderPath) { |