/** * @fileoverview Shared canvas column-name sanitizer. The two matrix-building * tools (`brapi_build_phenotype_matrix`, `brapi_export_genotype_matrix`) pivot * upstream IDs (`observationVariableDbId`, `variantDbId`) into dataframe column * names. The framework's canvas registers tables through `assertValidIdentifier`, * which rejects any column whose name fails `/^[A-Za-z_][A-Za-z0-9_]{0,62}$/` or * matches a reserved SQL keyword. BrAPI DbIds are routinely numeric (Breedbase * uses integers) or collide with reserved words, so column names must be * sanitized to SQL-safe identifiers before registration — paired with a legend * mapping the safe name back to the original ID so the correlation is never lost. * * `sanitizeRowColumns` applies the same rules to whole spilled rows at the * `CanvasBridge.registerDataframe` choke point, so every generic `find_*` * spillover (not just the matrix pivots) is protected — a `/variants` row's * reserved `end` key no longer fails registration. * * @module mcp-server/tools/shared/canvas-columns */ /** * Sanitize an arbitrary upstream ID into a valid DuckDB column identifier. * Mirrors the framework's `CANVAS_IDENTIFIER_REGEX` (`/^[A-Za-z_][A-Za-z0-9_]{0,62}$/`): * replace illegal characters with `_`, prefix `v_` when the result would start * with a digit, truncate to 63 chars, and suffix `_` when the result collides * with a reserved SQL keyword. */ export declare function sanitizeColumnName(raw: string): string; /** * Sanitize a list of IDs into unique column names, preserving input order. When * two IDs sanitize to the same name, later collisions get a numeric suffix * (`_2`, `_3`, …). Returns the column names in order plus a legend mapping each * safe column name back to its original ID. */ export declare function buildUniqueColumns(ids: readonly string[]): { columns: string[]; toOriginal: Record; }; /** * Sanitize every column key across a spilled row set into SQL-safe DuckDB * identifiers, reusing {@link buildUniqueColumns}. Returns the (possibly * rewritten) rows plus a legend mapping each *renamed* safe column back to its * original upstream key — entries are added only for columns that actually * changed. When every key is already a valid identifier the input rows are * returned by reference and the legend is empty, so the common (all-safe) path * stays allocation-free. * * Centralizing this at `CanvasBridge.registerDataframe` keeps every spill * consumer safe by construction: a row carrying a reserved word (`end`, * `order`, …) or a digit-leading key no longer trips the framework's * `assertValidIdentifier` gate at table registration. */ export declare function sanitizeRowColumns(rows: ReadonlyArray>): { legend: Record; rows: Record[]; }; //# sourceMappingURL=canvas-columns.d.ts.map