import { type HygieneCommonOptions } from "../shared.js"; export interface CleanupEmptyFoldersOptions extends HygieneCommonOptions { /** Required. Root path to clean up under. */ root: string; /** Cap on deletions. Default 500. */ maxDeletions?: number; whatIf?: boolean; allowWrite?: boolean; baseline?: boolean; output?: string; format?: "json" | "csv" | "markdown"; /** * Permit operating against `/sitecore/system` and templates roots. * Off by default. Required even with `--what-if` to avoid surprise. */ force?: boolean; /** * Additional template IDs to treat as folders, beyond the well-known * Sitecore folder templates. Accept any case + dashed/curly/flat * GUID form — values are normalised before comparison. Repeat or * comma-separate at the CLI layer. * * Without an allowlist, the cleanup would delete *any* leaf item * (Pages, Datasources, etc.) the moment its children were emptied — * the original implementation had exactly this footgun in production. */ folderTemplateIds?: string[]; /** * Treat any item whose template name matches this regular expression * as a folder for deletion purposes. Off by default. Use with care — * a permissive pattern (e.g. `.*Folder.*`) will sweep "Folder Settings" * or "Folder Mapping" templates alongside actual folders. The default * folder-id allowlist is the safer surface for most operators. */ templateNamePattern?: string; /** * Disable the folder-template gate and revert to the pre-2026 * behaviour of deleting any leaf item with zero children. Provided * only as an emergency escape hatch — pair with `--what-if` first * and a tightly scoped `--root` to avoid mass deletion of Page items. */ anyTemplate?: boolean; } export interface EmptyFolderAction { itemId: string; path: string; status: "deleted" | "what-if" | "failed"; error?: string; } /** * Delete folder-like items that have no children, recursively * bottom-up under `--root`. * * Strategy: * 1. Walk the tree depth-first via `getChildren`. * 2. At each node, recurse; if every child reports as "empty after * cleanup" (i.e. itself got deleted), and the node itself has * no remaining children, delete the node. * 3. Continue bubbling up — parent may become empty after its * children are deleted. * * Safety rails: * - `--root` required; no tenant-wide form. * - `/sitecore/system`, `/sitecore/templates`, `/sitecore/layout` * refused without `--force`. * - `--allow-write` (or env `allowWrite`) required outside * `--what-if`. * - `--max-deletions` caps total folder removals. * - Items that have content (non-folder template, fields with * values) are NOT touched — we ONLY delete items with zero * children, regardless of their template. If a "Page" item has * no children, the operator should clean it via `cleanup * duplicates` or similar, not here. */ export declare const runCleanupEmptyFolders: (options: CleanupEmptyFoldersOptions) => Promise;