import { type HygieneCommonOptions } from "../shared.js"; import { type ReferenceKind } from "../reference-kind.js"; /** Policy for handling external inbound references to the subtree. */ export type OrphanExternalRefsPolicy = /** * Empty the entire referring field. Cheap and correct for single-value * fields (droplists, single-link). Blunt for multi-value fields: * a treelist or multi-list field carrying ten GUIDs would lose all * ten, not just the one targeting the subtree. */ "clear" /** * Surgical removal — preserve sibling entries in multi-value fields. * Dispatches by field-value shape: `__Renderings`-style XML drops * just the `` elements pointing at the subtree; pipe- * separated multi-list / treelist fields drop just the offending * GUIDs. Single-value fields with no shape to preserve fall through * to a clear (empty-string write). */ | "prune" /** * Delete the subtree and do nothing to external referrers — accept * dangling refs as a tradeoff for speed. Skips the inbound-reference * scan entirely (fastest mode). Operator is expected to run `audit * broken-links` after the fact to find and triage the dangling refs. */ | "leave"; export interface CleanupSubtreeOptions extends HygieneCommonOptions { /** Required. Root path of the subtree to delete. */ path?: string; /** * Content root to scan for inbound references. Default `/sitecore` — * the entire CMS, so refs from any root are caught. Narrow to * `/sitecore/content` etc. for faster runs at the cost of missing * refs from outside that root. */ scanRoot?: string; /** * What to do when external items have field values referencing items * inside the subtree. Default: refuse (hard-block) and print the * blockers. With `clear`, the audit clears those field values before * walking the deletion bottom-up. */ orphanExternalRefs?: OrphanExternalRefsPolicy; /** * Permit operating on protected platform subtrees. Off by default — * `/sitecore/system`, `/sitecore/templates/System`, `/sitecore/layout/Layouts/System`, * and the Recycle Bin are all refused without `--force`. */ force?: boolean; /** Hard cap on items deleted. Default 1000. Protects against runaway scope. */ maxDeletions?: number; whatIf?: boolean; allowWrite?: boolean; index?: string; concurrency?: number; pageParallelism?: number; batchSize?: number; cache?: boolean; limit?: number; /** Restrict the inbound-ref scan to these field names. */ fields?: string[]; } export interface InboundBlocker { /** Item that holds the referencing field — outside the subtree. */ referrerItemId: string; referrerPath: string; referrerTemplateName: string | null; fieldName: string; /** * Structured reference category derived from `fieldName`. Lets the * operator distinguish "base-template inheritance" (catastrophic — * orphans every inheritor's fields) from "field-value" (recoverable * — clear the field, refs go away). See * [./reference-kind](./reference-kind.ts) for the mapping table. */ referenceKind: ReferenceKind; /** Item inside the subtree the field value references. */ targetItemId: string; /** * The field's value at scan time. Captured so `prune` can compute * surgical removals without a re-read; `clear` ignores it. */ fieldValue?: string; /** * Whether the referring field was successfully written (cleared OR * pruned) in apply mode. Stays undefined in what-if mode and on * update failures. Name kept for back-compat with the v1.1 API. */ cleared?: boolean; } export interface SubtreeDeletion { itemId: string; path: string; status: "deleted" | "what-if" | "failed"; error?: string; } export interface CleanupSubtreeResult { blockers: InboundBlocker[]; deletions: SubtreeDeletion[]; /** What this run was — useful for downstream tooling. */ policy: OrphanExternalRefsPolicy | "block"; whatIf: boolean; } /** * Bottom-up cascade delete of a Sitecore subtree. * * Steps: * 1. Resolve `--path` to an itemId; refuse protected roots. * 2. Enumerate the subtree via `_path CONTAINS ` and * sort path-length-descending so leaves delete before their * parents. * 3. Scan `--scan-root` (default `/sitecore`) for items outside the * subtree whose field values reference any item inside. * 4. Hard-block by default. With `--orphan-external-refs clear`, * empty each referring field, then proceed. * 5. Walk the deletion list and delete each item. * * Safety rails match the rest of `scai hygiene cleanup`: `--what-if` for * plan-only mode, `--allow-write` enforced outside what-if, * `--max-deletions` blast-radius cap. */ export declare const runCleanupSubtree: (options: CleanupSubtreeOptions) => Promise;