Skip to content
← Public packages

@kody/google

Call Gmail, Calendar, Tasks, Drive, Docs, Sheets, People, YouTube, and Analytics through saved Google OAuth.

src/sheets.ts

146 lines · 4.4 KB · TypeScript
import { requestGoogle } from './core.ts'
import type { GoogleAuthParams } from './accounts.ts'
import type { JsonObject } from './types.ts'

export type SheetsGetParams = GoogleAuthParams & {
	spreadsheetId: string
	ranges?: string | string[]
	includeGridData?: boolean
}

export type SheetsCreateParams = GoogleAuthParams & {
	title?: string
	dryRun?: boolean
}

export type SheetsValuesParams = GoogleAuthParams & {
	spreadsheetId: string
	range: string
	majorDimension?: string
	valueRenderOption?: string
	dateTimeRenderOption?: string
}

export type SheetsUpdateValuesParams = SheetsValuesParams & {
	values: unknown[][]
	valueInputOption?: string
	dryRun?: boolean
}

export type SheetsAppendValuesParams = SheetsUpdateValuesParams & {
	insertDataOption?: string
}

/**
 * Return the Google Sheets helper namespace.
 * Built-in Google includes the spreadsheets scope.
 * @returns Helper namespace or overview for this Google product.
 * @example
 * import sheets from 'kody:@kody/google/sheets'
 * const values = await sheets().getValues({ spreadsheetId: '...', range: 'Sheet1!A1:C10' })
 */
export default function sheets() {
	return { getSpreadsheet, createSpreadsheet, getValues, updateValues, appendValues }
}

export async function getSpreadsheet(params: SheetsGetParams): Promise<JsonObject> {
	if (!params.spreadsheetId) throw new Error('getSpreadsheet requires spreadsheetId.')
	return (await requestGoogle({
		...params,
		api: 'sheets',
		path: '/v4/spreadsheets/' + encodeURIComponent(params.spreadsheetId),
		query: { ranges: params.ranges, includeGridData: params.includeGridData },
	})) as JsonObject
}

export async function createSpreadsheet(params: SheetsCreateParams = {}): Promise<JsonObject> {
	const { title = 'Untitled spreadsheet', dryRun = false } = params
	if (dryRun) return { dryRun: true, account: params.account, title }
	return (await requestGoogle({
		...params,
		api: 'sheets',
		method: 'POST',
		path: '/v4/spreadsheets',
		body: { properties: { title } },
	})) as JsonObject
}

export async function getValues(params: SheetsValuesParams): Promise<JsonObject> {
	if (!params.spreadsheetId) throw new Error('getValues requires spreadsheetId.')
	if (!params.range) throw new Error('getValues requires range.')
	return (await requestGoogle({
		...params,
		api: 'sheets',
		path:
			'/v4/spreadsheets/' +
			encodeURIComponent(params.spreadsheetId) +
			'/values/' +
			encodeURIComponent(params.range),
		query: {
			majorDimension: params.majorDimension,
			valueRenderOption: params.valueRenderOption,
			dateTimeRenderOption: params.dateTimeRenderOption,
		},
	})) as JsonObject
}

export async function updateValues(params: SheetsUpdateValuesParams): Promise<JsonObject> {
	const { spreadsheetId, range, values, valueInputOption = 'USER_ENTERED', dryRun = false } = params
	if (!spreadsheetId) throw new Error('updateValues requires spreadsheetId.')
	if (!range) throw new Error('updateValues requires range.')
	if (!Array.isArray(values)) throw new Error('updateValues requires values as an array of rows.')
	if (dryRun) {
		return { dryRun: true, account: params.account, spreadsheetId, range, values, valueInputOption }
	}
	return (await requestGoogle({
		...params,
		api: 'sheets',
		method: 'PUT',
		path:
			'/v4/spreadsheets/' +
			encodeURIComponent(spreadsheetId) +
			'/values/' +
			encodeURIComponent(range),
		query: { valueInputOption },
		body: { range, values, majorDimension: params.majorDimension },
	})) as JsonObject
}

export async function appendValues(params: SheetsAppendValuesParams): Promise<JsonObject> {
	const {
		spreadsheetId,
		range,
		values,
		valueInputOption = 'USER_ENTERED',
		insertDataOption,
		dryRun = false,
	} = params
	if (!spreadsheetId) throw new Error('appendValues requires spreadsheetId.')
	if (!range) throw new Error('appendValues requires range.')
	if (!Array.isArray(values)) throw new Error('appendValues requires values as an array of rows.')
	if (dryRun) {
		return {
			dryRun: true,
			account: params.account,
			spreadsheetId,
			range,
			values,
			valueInputOption,
			insertDataOption: insertDataOption ?? null,
		}
	}
	return (await requestGoogle({
		...params,
		api: 'sheets',
		method: 'POST',
		path:
			'/v4/spreadsheets/' +
			encodeURIComponent(spreadsheetId) +
			'/values/' +
			encodeURIComponent(range) +
			':append',
		query: { valueInputOption, insertDataOption },
		body: { range, values, majorDimension: params.majorDimension },
	})) as JsonObject
}