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;