/** * Value normalization between Sheets API cells and the canonical contracts. * * These helpers mirror the Apps Script operations' value semantics exactly: * whole-column registered ranges, the Excel 1900-system date serial * (days since 1899-12-30 UTC), the canonical UTC number format, NFC-normalized * strings, and the identity-from-cell rule used by the append/replay paths. */ import type { NormalizedCell } from "../../../../contracts/encoding/types.js"; /** A validated whole-column registered range with 1-based column positions. */ export interface ParsedRegisteredRange { readonly startColumn: number; readonly columnCount: number; } /** Parses `A:C`-style whole-column ranges like the Apps Script operations. */ export declare function parseRegisteredRange(value: string): ParsedRegisteredRange; import { columnNumber, columnLetters, quoteA1SheetName } from "../../../../contracts/sheets/googleSheetsApi.js"; export { columnNumber, columnLetters, quoteA1SheetName }; /** * Excel/Sheets 1900-system serial: whole days since 1899-12-30 UTC. Canonical * dates are always after the 1900-02-29 phantom day, so the serial is exactly * the UTC day offset (the same formula the Apps Script batch append uses). */ export declare function dateSerialFromIso(iso: string): number; /** * Converts a date serial back to the canonical UTC ISO timestamp. * * The epoch milliseconds are rounded to the nearest integer millisecond so * floating-point noise in the serial (or in the serial-to-milliseconds * product) cannot shift the rendered millisecond and break field-level * compare-and-set hashes; canonical ISO timestamps are always integral * milliseconds, so rounding recovers the exact value the serial was derived * from. Invalid serials (NaN or non-finite) still fail exactly like the * unrounded conversion: `new Date(...).toISOString()` throws a RangeError. */ export declare function isoFromDateSerial(serial: number): string; /** * Returns whether a cell number format is the canonical date format. * * The REST API returns `CellFormat.numberFormat` as a `{ type, pattern }` * object, never a bare string. The canonical check requires the DATE_TIME * type and a pattern that matches after stripping embedded quotes and * whitespace, so both the quoted pattern the provider writes and any * unquoted equivalent are recognized. Null or absent formats are tolerated * and are not dates. */ export declare function isCanonicalDateNumberFormat(format: unknown): boolean; /** * Converts one API cell value to a canonical normalized cell. * * A number whose cell format is the canonical date format becomes a date; * everything else keeps its raw kind. Formula and error cells fail closed * (the outbound provider never writes them and must not hash them as * literals). Blank cells (missing or empty value objects) become `null`. */ export declare function normalizedCellFromApiValue(value: unknown, numberFormat: unknown): NormalizedCell; /** * Normalizes a literal API cell for observation reads. * * Matches the Apps Script observation literal branch: explicit empty strings * and empty value objects become `null` (blank). Returns `undefined` for * shapes that are not a valid literal (formula/error/unknown) so the caller * can emit an `unsupported_cell_value` error cell instead of failing the * whole snapshot; type-invalid fields still fail closed. */ export declare function observationLiteralFromApiValue(value: unknown, numberFormat: unknown): NormalizedCell | undefined; /** * getValues-equivalent normalization for one REST cell. * * Formula cells resolve to their computed effective value, error cells to * their formatted error string (the Apps Script fast-path limitation: a * "#REF!" error cell becomes a literal string), and literal cells to their * user-entered value. Blank cells — including explicit empty strings — * become `null`; unsupported shapes fail closed exactly like the Apps * Script table read throws. */ export declare function computedValueFromApiCell(value: unknown, numberFormat: unknown): NormalizedCell; /** * Blank-row rule shared by the values-only read and observation paths. * * A cell is blank when it has no value at all; checkbox columns additionally * treat an unchecked (boolValue false) cell as blank, mirroring the Apps * Script `isBlankRow_` rule. Formula cells are blank only when their computed * value is an empty string (getValues semantics). */ export declare function isComputedBlankCell(value: unknown, checkboxColumn: boolean): boolean; /** * Converts a canonical normalized cell to the API userEnteredValue shape. * * Dates become their Excel serial number; the canonical number format is * applied separately by the batch builder so it can keep the format field * mask isolated from the value write. */ export declare function toApiUserEnteredValue(cell: NormalizedCell): { readonly userEnteredValue: { readonly stringValue?: string; readonly numberValue?: number; readonly boolValue?: boolean; }; }; /** * Derives the visible business identity from a normalized cell, exactly like * the Apps Script `identityFromCell_`: non-empty strings and finite numbers. */ export declare function identityFromNormalizedCell(cell: NormalizedCell | null): string | null; /** Returns whether an API cell is blank (missing value or empty object). */ export declare function isBlankApiCell(value: unknown): boolean; //# sourceMappingURL=valueNormalization.d.ts.map