/** * Preflight row normalization, indexes, and sheet/grid lookup. * * Nonblank target rows are normalized into typed `PreflightRow` values with * their anchor evidence and visible identity; the identity index fails closed * on duplicates while the anchor index keeps only the FIRST row per anchor * value (duplicated anchors are evidence, never rewritten), and both derive * the next append row. Sheet and grid lookup helpers resolve titles to * validated grids for the preflight data read and the observation/ * provisioning readers. */ import type { Presence } from "../../../../contracts/state/index.js"; import { type SyncMissingTabOperation } from "../../../../contracts/sheets/errors.js"; import type { ParsedCellNumberFormat, ParsedGridData, ParsedSheet, ParsedSpreadsheetDocument, PreflightRow } from "./preflightTypes.js"; /** * Resolves a tab by title or fails closed when it is absent from an * enumeration. `operation` classifies the missing-tab invalid state so the * caller's step (preflight vs postcondition recovery) is reported; it * defaults to the preflight step. */ export declare function requireSheetByTitle(sheets: readonly ParsedSheet[], title: string, operation?: SyncMissingTabOperation): ParsedSheet; export declare function findSheetByTitle(sheets: readonly ParsedSheet[], title: string): ParsedSheet | undefined; export declare function requireGridDataForSheet(document: ParsedSpreadsheetDocument, sheetId: number): ParsedGridData; /** Returns the ordered per-range grid list of one sheet, failing closed. */ export declare function requireSheetGrids(document: ParsedSpreadsheetDocument, sheetId: number): readonly ParsedGridData[]; /** Takes the single grid a one-range reader must have received. */ export declare function requireSingleGrid(grids: readonly ParsedGridData[], sheetId: number): ParsedGridData; /** * Resolves the raw CellData at one absolute 1-based coordinate across an * ordered per-range GridData list of one sheet. The first range covering the * coordinate wins; ranges of one request share one sheet snapshot, so * overlapping ranges never mix evidence. Out of every band → `null`. */ export declare function resolveGridCell(grids: readonly ParsedGridData[], rowNumber: number, absoluteColumn: number): unknown; /** * Merges a scoped preflight read's per-range grids (one header row plus one * 1-column band per tab-wide key column) into ONE dense logical grid over * the full registered range, so the historical header/blank-row/anchor * normalization runs unchanged. Columns outside the requested bands resolve * to blank cells (`null`) — they are only ever hashed for rows the scoped * verification read re-reads with full width and formats. */ export declare function synthesizeScopedTargetGrid(grids: readonly ParsedGridData[], range: { readonly startColumn: number; readonly columnCount: number; }): ParsedGridData; /** * Returns the 1-based absolute column of the row-check formula column of * one registered range, or `undefined` for projections without one. The * check column lives DIRECTLY AFTER the registered range (outside every * range-scoped read/hash rule) and only User_Input tabs carry it. * * This is the UNVERIFIED geometric position: the column is only USED once * `buildRouteContext` has seen the `__hikoutei_row_check` header cell there * (a provisioned tab); legacy tabs keep `PreflightContext.checkColumn` * undefined and receive no formula writes. */ export declare function checkColumnFor(registeredRange: string, projection: string): number | undefined; /** * Picks the whole-table grid of a full-shape read from an ordered * per-range grid list. The registered-span grid (starts at the range's * first cell) must appear EXACTLY once — a duplicate is the proven * malformed multi-grid reply a single-range reader fails closed on — while * additional out-of-range probe bands (the row-check header cell) are * tolerated because the full-shape user_input read requests them. */ export declare function pickRegisteredGrid(grids: readonly ParsedGridData[], range: { readonly startColumn: number; readonly columnCount: number; }, sheetId: number): ParsedGridData; /** Normalizes nonblank grid rows into typed preflight rows. */ export declare function readRows(data: ParsedGridData, range: { readonly startColumn: number; readonly columnCount: number; }, headers: readonly string[], identityField: Presence, anchorColumn: number | undefined, /** * Scoped-read blank rule. The full-width read treats any nonblank user * field as row content; a column-scoped read only sees the key columns. * With a registered identity the rule is identity-cell nonblank: the * provider always writes the identity on its content rows, so a key-blank * row inside the content area is a human-drift candidate that the caller * detects via the contiguity check and answers with a whole-table * full-evidence re-read (non-key content can never be silently skipped; * see `hasScopedKeyRowGap` in `preflightContext.ts`). Without a registered * identity there is no required-identity validation to preserve, so the * anchor cell marks content (an anchor-only row stays blank, matching the * historical system-column rule). A hidden row BELOW the last visible key * row cannot be detected from narrowed columns at all: appends shift it * down (`insertDimension`, never overwrite) and the inbound observation * path still gates it — the pre-cursor whole-table read is the upgrade * path if a deployment needs that case refused too. */ scoped?: boolean): readonly PreflightRow[]; /** * Builds the row -> anchor-list index from the system row-id column. * * The anchor is the LAST column cell value of the user_input registered * range: any non-empty string value counts as the row's anchor (the column * position is the identity proof; the `sync-anchor:` prefix is the format of * observation- and append-assigned anchors, but flush-derived anchors keep * the mapping's deterministic format such as `entity:`). The header row * is skipped so the `__hikoutei_row_id` header cell never becomes a * pseudo-anchor. Blank cells, whitespace-only cells, empty strings, and * non-string values are not anchors and are treated as missing by the * caller. `anchorColumn` is 1-based; projections without a system column * pass `undefined` and yield no anchors. */ export declare function readAnchorIndex(data: ParsedGridData, anchorColumn: number | undefined): ReadonlyMap; /** Extracts one anchor value from a system-column cell, if any. */ export declare function anchorFromColumnValue(value: unknown): string | undefined; /** * Returns the 1-based system row-id column of one registered range, or * `undefined` for projections without a system column (only user_input tabs * carry one, always as the LAST column of the registered range). */ export declare function anchorColumnFor(registeredRange: string, projection: string): number | undefined; export declare function indexRows(rows: readonly PreflightRow[], options?: { readonly deferIdentityDupFailClosed: boolean; }): { readonly byAnchor: ReadonlyMap; readonly byIdentity: ReadonlyMap; readonly nextAppendRow: number; }; /** * Reads the visible cells of one 1-based row over the registered range. * * `null` entries mark blank cells, matching the sparse values arrays the API * returns (a row's values array may be narrower than the requested range). */ export declare function gridRowCells(data: ParsedGridData, rowNumber: number, startColumn: number, columnCount: number): readonly unknown[]; /** * Extracts the number format of one API cell, if any. * * The REST API models `CellFormat.numberFormat` as a `{ type, pattern }` * object, never a bare string. Every present wrapper (`userEnteredFormat`, * `effectiveFormat`, and their nested `numberFormat` containers) is * validated before preference, so a valid entered format can never hide a * malformed effective format; the user-entered format wins over the * effective format only when both are well-formed. */ export declare function apiCellNumberFormat(value: unknown): ParsedCellNumberFormat | undefined; //# sourceMappingURL=preflightRows.d.ts.map