@openinc/parse-server-opendash
Version:
Parse Server Cloud Code for open.INC Stack.
155 lines (154 loc) • 6.54 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.FeatureFilter = void 0;
const isFeatureEnabled_1 = require("../../config/helper/isFeatureEnabled");
/**
* Feature-based filtering service for documentation
*/
class FeatureFilter {
/**
* Filter folders and files based on their feature configuration
*/
static filterByFeature(root) {
console.log(`[FeatureFilter] Starting feature-based filtering for root folder: ${root.name}`);
const originalFileCount = this.countTotalFiles(root);
const originalFolderCount = this.countTotalFolders(root);
const filtered = this.filterFolder(root);
const filteredFileCount = this.countTotalFiles(filtered);
const filteredFolderCount = this.countTotalFolders(filtered);
console.log(`[FeatureFilter] Filtering complete:`, {
originalFiles: originalFileCount,
filteredFiles: filteredFileCount,
excludedFiles: originalFileCount - filteredFileCount,
originalFolders: originalFolderCount,
filteredFolders: filteredFolderCount,
excludedFolders: originalFolderCount - filteredFolderCount,
});
return filtered;
}
/**
* Recursively filter a folder and its contents based on feature enablement
*/
static filterFolder(folder) {
const folderPath = folder.path || folder.name;
// Check if this folder should be excluded based on feature
if (folder.config.feature && !(0, isFeatureEnabled_1.isFeatureEnabled)(folder.config.feature)) {
console.log(`[FeatureFilter] Excluding folder '${folderPath}' (feature '${folder.config.feature}' is disabled)`);
// Return an empty folder structure to effectively exclude this folder
return {
...folder,
files: [],
subfolders: new Map(),
};
}
const originalFileCount = folder.files.length;
const originalSubfolderCount = folder.subfolders.size;
// Filter files in this folder
const filteredFiles = folder.files.filter((file) => {
// If file has no feature config, include it
if (!file.config?.feature)
return true;
// If file has feature config, check if it's enabled
const isEnabled = (0, isFeatureEnabled_1.isFeatureEnabled)(file.config.feature);
if (!isEnabled) {
console.log(`[FeatureFilter] Excluding file '${file.path}' (feature '${file.config.feature}' is disabled)`);
}
return isEnabled;
});
// Recursively filter subfolders
const filteredSubfolders = new Map();
for (const [name, subfolder] of folder.subfolders) {
const filteredSubfolder = this.filterFolder(subfolder);
// Only include subfolders that have content after filtering
// or don't have a feature restriction
if (this.hasContent(filteredSubfolder) || !subfolder.config.feature) {
filteredSubfolders.set(name, filteredSubfolder);
}
else {
console.log(`[FeatureFilter] Removing empty subfolder '${subfolder.path || subfolder.name}' after filtering`);
}
}
const excludedFiles = originalFileCount - filteredFiles.length;
const excludedSubfolders = originalSubfolderCount - filteredSubfolders.size;
if (excludedFiles > 0 || excludedSubfolders > 0) {
console.log(`[FeatureFilter] Filtered folder '${folderPath}':`, {
excludedFiles,
excludedSubfolders,
remainingFiles: filteredFiles.length,
remainingSubfolders: filteredSubfolders.size,
});
}
return {
...folder,
files: filteredFiles,
subfolders: filteredSubfolders,
};
}
/**
* Check if a folder has any content (files or non-empty subfolders)
*/
static hasContent(folder) {
// Has files
if (folder.files.length > 0)
return true;
// Has non-empty subfolders
for (const subfolder of folder.subfolders.values()) {
if (this.hasContent(subfolder))
return true;
}
return false;
}
/**
* Filter the flat file list to match the filtered folder structure
*/
static filterFileList(files, filteredRoot) {
console.log(`[FeatureFilter] Filtering file list: ${files.length} total files`);
const allowedPaths = new Set();
this.collectAllowedPaths(filteredRoot, "", allowedPaths);
console.log(`[FeatureFilter] Collected ${allowedPaths.size} allowed file paths`);
const filteredFiles = files.filter((file) => allowedPaths.has(file.path));
const excludedCount = files.length - filteredFiles.length;
if (excludedCount > 0) {
console.log(`[FeatureFilter] File list filtering complete: ${excludedCount} files excluded, ${filteredFiles.length} files remaining`);
}
else {
console.log(`[FeatureFilter] File list filtering complete: no files excluded`);
}
return filteredFiles;
}
/**
* Recursively collect all allowed file paths from the filtered folder structure
*/
static collectAllowedPaths(folder, currentPath, allowedPaths) {
// Add all files in this folder
for (const file of folder.files) {
allowedPaths.add(file.path);
}
// Recursively process subfolders
for (const [name, subfolder] of folder.subfolders) {
const subfolderPath = currentPath ? `${currentPath}/${name}` : name;
this.collectAllowedPaths(subfolder, subfolderPath, allowedPaths);
}
}
/**
* Count total files recursively in a folder structure
*/
static countTotalFiles(folder) {
let count = folder.files.length;
for (const subfolder of folder.subfolders.values()) {
count += this.countTotalFiles(subfolder);
}
return count;
}
/**
* Count total folders recursively in a folder structure
*/
static countTotalFolders(folder) {
let count = folder.subfolders.size;
for (const subfolder of folder.subfolders.values()) {
count += this.countTotalFolders(subfolder);
}
return count;
}
}
exports.FeatureFilter = FeatureFilter;