import { Range } from "./range.js"; import type { Address } from "./types.js"; import { CellMatrix } from "./utils/cell-matrix.js"; import { type DecodedRange } from "./utils/col-cache.js"; import { type SyntaxProbe } from "../formula/default-syntax-probe.js"; interface DefinedNameCell { sheetName?: string; address: string; row: number; col: number; mark?: boolean; } type CellLocation = Address | DecodedRange; interface DefinedNameModel { name: string; ranges: string[]; localSheetId?: number; /** Formula expression for formula-based defined names (e.g. "LAMBDA(x,y,x+y)") */ formulaExpression?: string; /** Original XML text — preserved for opaque names round-trip */ rawText?: string; /** * Classification determined by the semantic layer: * - "reference": pure cell/range union — stored in matrixMap * - "formula": parseable expression — stored in formulaMap * - "opaque": unrecognised content preserved for round-trip — stored in opaqueMap */ kind?: "reference" | "formula" | "opaque"; /** * `definedName/@hidden` — when `true`, emits `hidden="1"` on the * XML element. Used by chartEx `_xlchart.vN.M` defined names that * Excel creates automatically for every chartEx data reference; * these names are infrastructure, never intended for users, so * Excel hides them from the Name Manager UI. */ hidden?: boolean; } /** Stored entry for an opaque (unrecognised) defined name. */ interface OpaqueEntry { rawText: string; localSheetId?: number; } declare class DefinedNames { matrixMap: Record; /** * Formula-based defined names: storageKey → formula expression string. */ formulaMap: Record; /** * Tracks the localSheetId for each storage key. * If a key is not in this map, the name is workbook-scoped (global). */ localSheetIdMap: Record; /** * Tracks the `hidden` flag for each storage key. Used by chartEx * `_xlchart.vN.M` infrastructure names — Excel emits them with * `hidden="1"` to suppress the Name Manager UI. A missing key * means "not hidden" (the default). */ hiddenMap: Record; /** * Opaque defined names: storageKey → original text + optional localSheetId. */ opaqueMap: Record; /** * Reverse mapping: storageKey → original name (bare, without scope suffix). * Needed because storageKey encodes the scope, but consumers need the bare name. */ nameForKey: Record; /** * Optional explicit formula-syntax probe. When set, this is used to * classify non-range, non-wrapper defined-name text during `set model`. * When unset, the classifier falls back to the process-wide default * probe (set by `installFormulaEngine()`). When neither is available, * classification is conservative — non-range text becomes opaque. */ private readonly _explicitProbe; /** * @param probe Optional formula-syntax probe used when classifying * defined-name text. Injecting a probe here makes classification * deterministic for this instance regardless of process-global * `installFormulaEngine()` state. When omitted, the instance defers * to the default probe at classification time (see `set model`). */ constructor(probe?: SyntaxProbe); getMatrix(name: string): CellMatrix; add(locStr: string, name: string): void; /** * Register a hidden defined name that maps a chartEx `_xlchart.vN.M` * pointer to a worksheet range. Excel emits one of these for every * data reference in a chartEx chart: * * * * The chartEx then references `_xlchart.v1.0` from its `` * element instead of the worksheet range directly. Direct sheet * references in `` are rejected by Excel 2016+ with * "Removed Part: /xl/drawings/drawingN.xml (Drawing shape)" on * load, so chartEx data MUST go through this indirection. * * Same semantics as `add()` but also marks the name `hidden` so * it does not show up in Excel's Name Manager UI. * * @param locStr - Worksheet reference (e.g. `"Sheet1!$A$1:$A$3"`) * @param name - Defined name to register (e.g. `"_xlchart.v1.0"`) */ addHidden(locStr: string, name: string): void; addEx(location: CellLocation, name: string): void; /** * Register a formula-based defined name. * * Unlike `add()` which binds a name to a cell/range reference, this binds * a name to an arbitrary formula expression that will be evaluated at * calculation time. * * @param name - The defined name (e.g. "MyArray") * @param expression - The formula expression (e.g. "{1,2;3,4}", "LAMBDA(x,y,x+y)") */ addFormula(name: string, expression: string): void; remove(locStr: string, name: string): void; removeEx(location: CellLocation, name: string): void; removeAllNames(location: CellLocation): void; forEach(callback: (name: string, cell: DefinedNameCell) => void): void; getNames(addressStr: string): string[]; getNamesEx(address: Address): string[]; /** * Return all defined name entries in this collection, including scope info. * Each entry has the bare name and optional localSheetId. * Same bare name may appear multiple times with different scopes. */ getAllNames(): { name: string; localSheetId?: number; }[]; /** * Return all defined name entries with full details (name, ranges, scope). * * This is the primary enumeration API. Each entry is self-contained — * no second lookup is needed. Same bare name may appear multiple times * with different scopes. */ getAllEntries(): DefinedNameModel[]; _explore(matrix: CellMatrix, cell: DefinedNameCell): Range; /** * Get ranges for a specific scoped entry. * * Unlike `getRanges(name)` which uses the bare name (and may hit the * wrong scope when the same name exists both globally and locally), * this method uses the internal `storageKey` to look up the exact entry. */ getRangesScoped(name: string, localSheetId?: number): DefinedNameModel; getRanges(name: string, matrix?: CellMatrix): DefinedNameModel; normaliseMatrix(matrix: CellMatrix, sheetName: string): void; spliceRows(sheetName: string, start: number, numDelete: number, numInsert: number): void; spliceColumns(sheetName: string, start: number, numDelete: number, numInsert: number): void; get model(): DefinedNameModel[]; /** * Deserialise an array of `DefinedNameModel` entries (typically from XLSX parsing). * * Stage 2 of the two-phase design: each entry's `rawText` is classified * into reference / formula / opaque by `classifyDefinedName()`. Entries * that arrive without `rawText` (programmatic API) fall back to inspecting * the existing `ranges` and `formulaExpression` fields for compatibility. */ set model(value: DefinedNameModel[]); } export { DefinedNames, type DefinedNameModel };