import * as z from "zod" import { defineAction } from "../../../automation/actions" import { getGoogleSheetsApi, normalizeSpreadsheet } from "../lib/google-sheets" import { GOOGLE_SHEETS_WRITE_REQUIREMENT } from "../lib/scopes" import { SPREADSHEET_SCHEMA } from "../lib/schemas" const RECALCULATION_INTERVALS = { hourly: "HOUR", minutely: "MINUTE", onChange: "ON_CHANGE", } as const /** Creates a Google Sheets spreadsheet with optional initial sheets. */ export const createGoogleSpreadsheet = defineAction("Create Google spreadsheet") .describe("Creates a spreadsheet and returns its normalized metadata.") .account("google", GOOGLE_SHEETS_WRITE_REQUIREMENT) .input( z.object({ /** Formula recalculation policy. */ autoRecalc: z.enum(["onChange", "minutely", "hourly"]).optional(), /** Spreadsheet locale, such as `en_US`. */ locale: z.string().min(1).optional(), /** Initial sheets. Google creates one default sheet when omitted. */ sheets: z .object({ /** Initial allocated column count. */ columnCount: z.number().int().positive().optional(), /** Number of initially frozen columns. */ frozenColumnCount: z.number().int().nonnegative().optional(), /** Number of initially frozen rows. */ frozenRowCount: z.number().int().nonnegative().optional(), /** Whether the sheet is hidden. */ hidden: z.boolean().optional(), /** Initial allocated row count. */ rowCount: z.number().int().positive().optional(), /** Human-readable sheet title. */ title: z.string().trim().min(1), }) .array() .min(1) .optional(), /** Spreadsheet timezone, such as `America/New_York`. */ timeZone: z.string().min(1).optional(), /** Human-readable spreadsheet title. */ title: z.string().trim().min(1), }), ) .output(SPREADSHEET_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => { const { data } = await getGoogleSheetsApi( account.secret, ).spreadsheets.create({ requestBody: { properties: { autoRecalc: input.autoRecalc ? RECALCULATION_INTERVALS[input.autoRecalc] : undefined, locale: input.locale, timeZone: input.timeZone, title: input.title, }, sheets: input.sheets?.map((sheet) => ({ properties: { gridProperties: { columnCount: sheet.columnCount, frozenColumnCount: sheet.frozenColumnCount, frozenRowCount: sheet.frozenRowCount, rowCount: sheet.rowCount, }, hidden: sheet.hidden, title: sheet.title, }, })), }, }) return normalizeSpreadsheet(data) })