UNPKG

@openinc/parse-server-opendash

Version:
168 lines (167 loc) 7.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DocumentationCleanup = void 0; const types_1 = require("../../../types"); /** * Service for cleaning up old documentation that no longer exists in the repository */ class DocumentationCleanup { /** * Remove old default documentation that is no longer present in the new import */ static async cleanupOldDocumentation(newStructure, user, tenant) { console.log(`[DocumentationCleanup] Starting cleanup of old default documentation`); // Collect all new git paths from the structure const newGitPaths = new Set(); this.collectGitPaths(newStructure, newGitPaths); console.log(`[DocumentationCleanup] Found ${newGitPaths.size} current git paths`); // Find all existing default documentation for this user/tenant const existingDocuments = await this.findExistingDefaultDocuments(user, tenant); const existingCategories = await this.findExistingDefaultCategories(user, tenant); const existingAssets = await this.findExistingAssets(user, tenant); console.log(`[DocumentationCleanup] Found ${existingDocuments.length} existing documents and ${existingCategories.length} existing categories`); // Identify documents to delete const documentsToDelete = existingDocuments.filter((doc) => { const gitPath = doc.get("gitPath"); return gitPath && !newGitPaths.has(gitPath); }); // Identify categories to delete const categoriesToDelete = existingCategories.filter((cat) => { const gitPath = cat.get("gitPath"); return gitPath && !newGitPaths.has(gitPath); }); console.log(`[DocumentationCleanup] Identified ${documentsToDelete.length} documents and ${categoriesToDelete.length} categories for deletion`); // Delete old documents let deletedDocuments = 0; for (const doc of documentsToDelete) { try { console.log(`[DocumentationCleanup] Deleting document: ${doc.get("title")} (gitPath: ${doc.get("gitPath")})`); await doc.destroy({ useMasterKey: true }); deletedDocuments++; } catch (error) { console.error(`[DocumentationCleanup] Failed to delete document ${doc.id}:`, error); } } // Delete old categories (delete in reverse order to handle parent-child relationships) let deletedCategories = 0; const sortedCategories = categoriesToDelete.sort((a, b) => { // Sort by gitPath depth (deeper paths first) to delete children before parents const aDepth = (a.get("gitPath") || "").split("/").length; const bDepth = (b.get("gitPath") || "").split("/").length; return bDepth - aDepth; }); for (const cat of sortedCategories) { try { console.log(`[DocumentationCleanup] Deleting category: ${cat.get("name")} (gitPath: ${cat.get("gitPath")})`); await cat.destroy({ useMasterKey: true }); deletedCategories++; } catch (error) { console.error(`[DocumentationCleanup] Failed to delete category ${cat.id}:`, error); } } // delete old assets let deletedAssets = 0; for (const asset of existingAssets) { const meta = asset.get("meta") || {}; if (meta.importedByDocumentation) { try { console.log(`[DocumentationCleanup] Deleting asset: ${asset.get("description")} (id: ${asset.id})`); await asset.destroy({ useMasterKey: true }); deletedAssets++; } catch (error) { console.error(`[DocumentationCleanup] Failed to delete asset ${asset.id}:`, error); } } } if (deletedAssets > 0) { console.log(`[DocumentationCleanup] Deleted ${deletedAssets} old assets imported by documentation`); } console.log(`[DocumentationCleanup] Cleanup complete: deleted ${deletedDocuments} documents and ${deletedCategories} categories`); return { deletedDocuments, deletedCategories }; } static async findExistingAssets(user, tenant) { const query = new Parse.Query(types_1.Assets); if (tenant) { query.equalTo("tenant", tenant); } if (user) { query.equalTo("user", user); } const assets = await query // @ts-expect-error .exists("meta.importedByDocumentation") .findAll({ useMasterKey: true }); return assets; } /** * Collect all git paths from the documentation structure */ static collectGitPaths(structure, gitPaths) { // Collect file paths for (const file of structure.allFiles) { gitPaths.add(file.path); } // Collect folder paths recursively this.collectFolderPaths(structure.root, "", gitPaths); } /** * Recursively collect folder paths */ static collectFolderPaths(folder, currentPath, gitPaths) { // Add current folder path (except root) if (currentPath) { gitPaths.add(currentPath); } // Recursively process subfolders for (const [name, subfolder] of folder.subfolders) { const subfolderPath = currentPath ? `${currentPath}/${name}` : name; this.collectFolderPaths(subfolder, subfolderPath, gitPaths); } } /** * Find all existing default documents for the given user/tenant */ static async findExistingDefaultDocuments(user, tenant) { const query = new Parse.Query(types_1.Documentation_Document) .equalTo("isDefault", true) .exists("gitPath"); // Only documents with gitPath (from repository) if (tenant) { query.equalTo("tenant", tenant); } if (user) { query.equalTo("user", user); } try { return await query.find({ useMasterKey: true }); } catch (error) { console.error(`[DocumentationCleanup] Failed to query existing documents:`, error); return []; } } /** * Find all existing default categories for the given user/tenant */ static async findExistingDefaultCategories(user, tenant) { const query = new Parse.Query(types_1.Documentation_Category) .equalTo("isDefault", true) .exists("gitPath"); // Only categories with gitPath (from repository) if (tenant) { query.equalTo("tenant", tenant); } if (user) { query.equalTo("user", user); } try { return await query.find({ useMasterKey: true }); } catch (error) { console.error(`[DocumentationCleanup] Failed to query existing categories:`, error); return []; } } } exports.DocumentationCleanup = DocumentationCleanup;