/** * Allow-edit ranges — named cell areas users may still edit while the sheet is protected. * * Access via {@link Worksheet.protectedRanges}. Add a range with a unique name and an * A1 address (or multi-area list). Optionally set a password so only people who know it * can edit that range in Excel. Empty collections are omitted when saving. * * This library stores the ranges in the file; it does not enforce locks at runtime. * * Citations: * - ECMA-376-1 §18.3.1.71 (`protectedRange`) / §18.3.1.72 (`protectedRanges`) * - transitional sml.xsd `CT_ProtectedRanges` / `CT_ProtectedRange` (~L2911–2928) * - `CT_Worksheet` sequence: after `sheetProtection`, before `scenarios` * - MS-OI29500 §2.1.643 (name uniqueness, charset, length; sqref ≥ 1 area) * - docs/specs/protected-ranges.md; docs/ooxml-mapping/protected-ranges.md */ import { CellRange } from '../address/cell-address'; /** * Values used when adding an allow-edit range with {@link ProtectedRanges.add}. */ export interface ProtectedRangeInput { /** Unique name for this range on the sheet (required). */ readonly name: string; /** * Cells the user may edit, in A1 form (required). * Multiple areas can be space-separated (for example `"A1:B2 D4:E5"`). */ readonly sqref: string; /** Optional password required in Excel to edit this range. */ readonly password?: string; } /** * One allow-edit range on a protected sheet. * * Changing {@link name}, {@link sqref}, or the password updates the sheet for the next save. */ export interface ProtectedRange { /** Unique name of this range on the sheet. */ name: string; /** Cell areas this range covers, in normalized A1 form. */ sqref: string; /** `true` when a password is set on this range. */ readonly hasPassword: boolean; /** * Set or replace the range password. Pass `undefined` or `""` to clear it. * * @throws InvalidArgumentError when a non-string password is provided */ setPassword(password: string | undefined): void; /** * Check whether a candidate password matches this range’s password. * * @returns `true` when the password matches * @throws InvalidProtectionError when there is no password, only a legacy password, or the candidate is wrong */ verifyPassword(password: string): boolean; } /** * Collection of allow-edit ranges on a worksheet ({@link Worksheet.protectedRanges}). */ export interface ProtectedRanges { /** How many ranges are defined. */ readonly count: number; /** All ranges, in the order they appear in the file / were added. */ list(): ReadonlyArray; /** Range at a zero-based index. */ get(index: number): ProtectedRange; /** Find a range by exact name (case-sensitive), or `undefined` if missing. */ getByName(name: string): ProtectedRange | undefined; /** * Add a new allow-edit range. * * @throws InvalidArgumentError when required fields are missing or the wrong type * @throws InvalidProtectionError when the name is invalid or already used */ add(input: ProtectedRangeInput): ProtectedRange; /** Remove the range at a zero-based index. */ removeAt(index: number): void; /** Remove a range previously returned by this collection. */ remove(range: ProtectedRange): void; /** Remove every allow-edit range. */ clear(): void; } /** * Internal wire entry for one `protectedRange`. * @private */ export interface ProtectedRangeEntry { name: string; ranges: CellRange[]; algorithmName: string | undefined; hashValue: string | undefined; saltValue: string | undefined; spinCount: number | undefined; /** Legacy ST_UnsignedShortHex — preserve-only; never authored. */ legacyPassword: string | undefined; /** Optional attribute `securityDescriptor` (preserve). */ securityDescriptorAttr: string | undefined; /** Child `securityDescriptor` element text (preserve; Office ignores). */ securityDescriptorElements: string[]; /** Extra attributes excluding modeled ones (XML fragment, no leading space). */ extraAttrsXml: string; } /** * Container-level attrs + entries for worksheet XML model. * @private */ export interface ProtectedRangesModel { readonly extraAttrsXml: string; readonly entries: ReadonlyArray; } /** * Host notifications for protected-range mutations. * @private */ export interface ProtectedRangesHost { markDirty(): void; } /** * Mutable protected-ranges store. * @private */ export declare class ProtectedRangesImpl implements ProtectedRanges { private readonly entries; private readonly handles; private host; private _extraAttrsXml; constructor(initial?: ProtectedRangesModel); /** @private */ bindHost(host: ProtectedRangesHost): void; readonly count: number; list(): ReadonlyArray; get(index: number): ProtectedRange; getByName(name: string): ProtectedRange | undefined; add(input: ProtectedRangeInput): ProtectedRange; removeAt(index: number): void; remove(range: ProtectedRange): void; clear(): void; /** * Replace contents from parse (does not mark dirty). * @private */ replaceFromParse(model: ProtectedRangesModel): void; /** * Snapshot for serialize. * @private */ toModel(): ProtectedRangesModel; private applyModel; private handleFor; } /** * Validate an allow-edit range name under Office authoring rules * (MS-OI29500 §2.1.643). * * @throws InvalidProtectionError when the name is invalid * @private */ export declare function validateProtectedRangeName(name: string): string; /** * Office name charset check (authoring). * @private */ export declare function isValidProtectedRangeName(name: string): boolean; /** * Parse multi-area A1 sqref for protected ranges. * @throws InvalidArgumentError / InvalidProtectionError * @private */ export declare function parseProtectedSqref(sqref: string): CellRange[]; /** * Format ranges as space-separated compact A1 sqref. * @private */ export declare function formatProtectedSqref(ranges: ReadonlyArray): string; /** * CT_Worksheet local names that appear **before** `protectedRanges` after sheetData. * Citation: transitional sml.xsd `CT_Worksheet`. */ export declare const PROTECTED_RANGES_PREDECESSORS_AFTER_SHEET_DATA: ReadonlyArray; /** * CT_Worksheet local names that appear **after** `protectedRanges`. * Citation: transitional sml.xsd `CT_Worksheet`. */ export declare const PROTECTED_RANGES_SUCCESSORS: ReadonlyArray; /** * Index at which to insert serialized `protectedRanges` among after-sheetData siblings. */ export declare function findProtectedRangesInsertIndex(afterSheetDataLocals: ReadonlyArray): number; /** * Empty model (no protected ranges). * @private */ export declare const EMPTY_PROTECTED_RANGES: ProtectedRangesModel; /** * Parse `protectedRanges` element XML into a model. * Soft-skips individual bad children (missing name/sqref). * @private */ export declare function parseProtectedRangesXml(xml: string): ProtectedRangesModel; /** * Serialize model to a `protectedRanges` element, or `undefined` when empty. * @private */ export declare function serializeProtectedRangesXml(model: ProtectedRangesModel): string | undefined;