import * as z from "zod" import { defineAction } from "../../../automation/actions" import { getGoogleSheetsApi, normalizeSpreadsheetId, resolveGridRange, } from "../lib/google-sheets" import { GOOGLE_SHEETS_WRITE_REQUIREMENT } from "../lib/scopes" import { GRID_RANGE_SCHEMA, NORMALIZED_GRID_RANGE_SCHEMA, SPREADSHEET_REFERENCE_SCHEMA, } from "../lib/schemas" /** Sorts rows within a structured range using ordered column specifications. */ export const sortGoogleSheetsRange = defineAction("Sort Google Sheets range") .describe("Sorts a range by one or more one-based sheet columns.") .account("google", GOOGLE_SHEETS_WRITE_REQUIREMENT) .input( z.object({ /** One-based structured grid range to sort. */ range: GRID_RANGE_SCHEMA, /** Ordered sort columns and directions. */ sortBy: z .object({ /** One-based absolute sheet column. */ column: z.number().int().positive(), /** Sort direction. */ direction: z.enum(["ascending", "descending"]).optional(), }) .array() .min(1), /** Spreadsheet ID or standard Google Sheets URL. */ spreadsheet: SPREADSHEET_REFERENCE_SCHEMA, }), ) .output(NORMALIZED_GRID_RANGE_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => { const sheetsApi = getGoogleSheetsApi(account.secret) const spreadsheetId = normalizeSpreadsheetId(input.spreadsheet) const range = await resolveGridRange(sheetsApi, spreadsheetId, input.range) await sheetsApi.spreadsheets.batchUpdate({ requestBody: { requests: [ { sortRange: { range, sortSpecs: input.sortBy.map(({ column, direction }) => ({ dimensionIndex: column - 1, sortOrder: direction === "descending" ? "DESCENDING" : "ASCENDING", })), }, }, ], }, spreadsheetId, }) return range })