import * as z from "zod" import { defineAction } from "../../../automation/actions" import { getGoogleSheetsApi, normalizeSpreadsheetId, normalizeTable, resolveGridRange, resolveTable, toGoogleTableColumn, } from "../lib/google-sheets" import { toGoogleTableRowsPropertiesUpdate } from "../lib/formatting" import { GOOGLE_SHEETS_WRITE_REQUIREMENT } from "../lib/scopes" import { GRID_RANGE_SCHEMA, SPREADSHEET_REFERENCE_SCHEMA, TABLE_COLUMN_INPUT_SCHEMA, TABLE_REFERENCE_SCHEMA, TABLE_SCHEMA, TABLE_STYLE_UPDATE_SCHEMA, } from "../lib/schemas" /** Updates a native table's name, range, or column configuration. */ export const updateGoogleSheetsTable = defineAction( "Update Google Sheets table", ) .describe("Updates the common structural properties of a native table.") .account("google", GOOGLE_SHEETS_WRITE_REQUIREMENT) .input( z .object({ /** Replacement native column configuration. */ columns: TABLE_COLUMN_INPUT_SCHEMA.array().min(1).optional(), /** New native table name. */ name: z.string().trim().min(1).optional(), /** New structured table range. */ range: GRID_RANGE_SCHEMA.optional(), /** Spreadsheet ID or standard Google Sheets URL. */ spreadsheet: SPREADSHEET_REFERENCE_SCHEMA, /** Native header and body-band color updates. Null restores a default. */ style: TABLE_STYLE_UPDATE_SCHEMA.optional(), /** Existing native table name or immutable table ID. */ table: TABLE_REFERENCE_SCHEMA, }) .refine( ({ columns, name, range, style }) => columns !== undefined || name !== undefined || range !== undefined || style !== undefined, "At least one table property must be updated.", ), ) .output(TABLE_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => { const spreadsheetId = normalizeSpreadsheetId(input.spreadsheet) const sheetsApi = getGoogleSheetsApi(account.secret) const { table } = await resolveTable(sheetsApi, spreadsheetId, input.table) const tableId = table.tableId if (!tableId) throw new Error("Google returned a table without an ID.") await sheetsApi.spreadsheets.batchUpdate({ requestBody: { requests: [ { updateTable: { fields: [ input.columns === undefined ? undefined : "columnProperties", input.name === undefined ? undefined : "name", input.range === undefined ? undefined : "range", input.style?.firstBandColor === undefined ? undefined : "rowsProperties.firstBandColorStyle", input.style?.headerColor === undefined ? undefined : "rowsProperties.headerColorStyle", input.style?.secondBandColor === undefined ? undefined : "rowsProperties.secondBandColorStyle", ] .filter((field) => field !== undefined) .join(","), table: { columnProperties: input.columns?.map(toGoogleTableColumn), name: input.name, range: input.range ? await resolveGridRange( sheetsApi, spreadsheetId, input.range, ) : undefined, rowsProperties: input.style ? toGoogleTableRowsPropertiesUpdate(input.style) : undefined, tableId, }, }, }, ], }, spreadsheetId, }) return normalizeTable( (await resolveTable(sheetsApi, spreadsheetId, tableId)).table, ) })