(file: string)
| 562 | } |
| 563 | |
| 564 | async delete(file: string): Promise<void> { |
| 565 | let fileName = file |
| 566 | if (!fileName.endsWith('.zim')) { |
| 567 | fileName += '.zim' |
| 568 | } |
| 569 | |
| 570 | const basePath = resolve(join(process.cwd(), ZIM_STORAGE_PATH)) |
| 571 | const fullPath = resolve(join(basePath, fileName)) |
| 572 | |
| 573 | // Prevent path traversal — resolved path must stay within the storage directory |
| 574 | if (!fullPath.startsWith(basePath + sep)) { |
| 575 | throw new Error('Invalid filename') |
| 576 | } |
| 577 | |
| 578 | const exists = await getFileStatsIfExists(fullPath) |
| 579 | if (!exists) { |
| 580 | throw new Error('not_found') |
| 581 | } |
| 582 | |
| 583 | await deleteFileIfExists(fullPath) |
| 584 | |
| 585 | // Remove from kiwix library XML so --monitorLibrary stops serving the deleted file |
| 586 | const kiwixLibraryService = new KiwixLibraryService() |
| 587 | await kiwixLibraryService.removeBook(fileName).catch((err) => { |
| 588 | logger.error(`[ZimService] Failed to remove ${fileName} from kiwix library:`, err) |
| 589 | }) |
| 590 | |
| 591 | // Clean up InstalledResource entry |
| 592 | const parsed = CollectionManifestService.parseZimFilename(fileName) |
| 593 | if (parsed) { |
| 594 | await InstalledResource.query() |
| 595 | .where('resource_id', parsed.resource_id) |
| 596 | .where('resource_type', 'zim') |
| 597 | .delete() |
| 598 | logger.info(`[ZimService] Deleted InstalledResource entry for: ${parsed.resource_id}`) |
| 599 | } |
| 600 | |
| 601 | // If this file was the active Wikipedia selection, clear the selection |
| 602 | try { |
| 603 | const selection = await WikipediaSelection.query().first() |
| 604 | if (selection && selection.filename === fileName) { |
| 605 | selection.option_id = 'none' |
| 606 | selection.status = 'none' |
| 607 | selection.filename = null |
| 608 | selection.url = null |
| 609 | await selection.save() |
| 610 | logger.info(`[ZimService] Cleared WikipediaSelection after deleting ${fileName}`) |
| 611 | } |
| 612 | } catch (error) { |
| 613 | logger.error(`[ZimService] Failed to clear WikipediaSelection after deleting ${fileName}:`, error) |
| 614 | } |
| 615 | } |
| 616 | |
| 617 | // Wikipedia selector methods |
| 618 |
no test coverage detected