Skip to content

Commit 01e9016

Browse files
committed
fix(google-sheets): update google sheets tools to take in both an array of objects and an array of arrays
1 parent c5e5c67 commit 01e9016

File tree

4 files changed

+109
-7
lines changed

4 files changed

+109
-7
lines changed

sim/blocks/blocks/google_sheets.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export const GoogleSheetsBlock: BlockConfig<GoogleSheetsResponse> = {
8282
title: 'Values',
8383
type: 'long-input',
8484
layout: 'full',
85-
placeholder: 'Enter values as JSON array of arrays (e.g., [["A1", "B1"], ["A2", "B2"]])',
85+
placeholder: 'Enter values as JSON array of arrays (e.g., [["A1", "B1"], ["A2", "B2"]]) or an array of objects (e.g., [{"name":"John", "age":30}, {"name":"Jane", "age":25}])',
8686
condition: { field: 'operation', value: 'write' },
8787
},
8888
{
@@ -102,7 +102,7 @@ export const GoogleSheetsBlock: BlockConfig<GoogleSheetsResponse> = {
102102
title: 'Values',
103103
type: 'long-input',
104104
layout: 'full',
105-
placeholder: 'Enter values as JSON array of arrays (e.g., [["A1", "B1"], ["A2", "B2"]])',
105+
placeholder: 'Enter values as JSON array of arrays (e.g., [["A1", "B1"], ["A2", "B2"]]) or an array of objects (e.g., [{"name":"John", "age":30}, {"name":"Jane", "age":25}])',
106106
condition: { field: 'operation', value: 'update' },
107107
},
108108
{
@@ -122,7 +122,7 @@ export const GoogleSheetsBlock: BlockConfig<GoogleSheetsResponse> = {
122122
title: 'Values',
123123
type: 'long-input',
124124
layout: 'full',
125-
placeholder: 'Enter values as JSON array of arrays (e.g., [["A1", "B1"], ["A2", "B2"]])',
125+
placeholder: 'Enter values as JSON array of arrays (e.g., [["A1", "B1"], ["A2", "B2"]]) or an array of objects (e.g., [{"name":"John", "age":30}, {"name":"Jane", "age":25}])',
126126
condition: { field: 'operation', value: 'append' },
127127
},
128128
{

sim/tools/google_sheets/append.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,40 @@ export const appendTool: ToolConfig<GoogleSheetsToolParams, GoogleSheetsAppendRe
7878
}
7979
}
8080

81-
// Validate that processedValues is actually an array of arrays
82-
if (!Array.isArray(processedValues)) {
81+
// New logic to handle array of objects
82+
if (Array.isArray(processedValues) && processedValues.length > 0 && typeof processedValues[0] === 'object' && !Array.isArray(processedValues[0])) {
83+
// It's an array of objects
84+
85+
// First, extract all unique keys from all objects to create headers
86+
const allKeys = new Set<string>()
87+
processedValues.forEach((obj: any) => {
88+
if (obj && typeof obj === 'object') {
89+
Object.keys(obj).forEach(key => allKeys.add(key))
90+
}
91+
})
92+
const headers = Array.from(allKeys)
93+
94+
// Then create rows with object values in the order of headers
95+
const rows = processedValues.map((obj: any) => {
96+
if (!obj || typeof obj !== 'object') {
97+
// Handle non-object items by creating an array with empty values
98+
return Array(headers.length).fill('')
99+
}
100+
return headers.map(key => {
101+
const value = obj[key]
102+
// Handle nested objects/arrays by converting to JSON string
103+
if (value !== null && typeof value === 'object') {
104+
return JSON.stringify(value)
105+
}
106+
return value === undefined ? '' : value
107+
})
108+
})
109+
110+
// Add headers as the first row, then add data rows
111+
processedValues = [headers, ...rows]
112+
}
113+
// Continue with existing logic for other array types
114+
else if (!Array.isArray(processedValues)) {
83115
processedValues = [[String(processedValues)]]
84116
} else if (!processedValues.every((item: any) => Array.isArray(item))) {
85117
// If it's an array but not all elements are arrays, wrap each element

sim/tools/google_sheets/update.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,44 @@ export const updateTool: ToolConfig<GoogleSheetsToolParams, GoogleSheetsUpdateRe
4444
'Content-Type': 'application/json',
4545
}),
4646
body: (params) => {
47+
let processedValues: any = params.values || []
48+
49+
// Handle array of objects
50+
if (Array.isArray(processedValues) && processedValues.length > 0 && typeof processedValues[0] === 'object' && !Array.isArray(processedValues[0])) {
51+
// It's an array of objects
52+
53+
// First, extract all unique keys from all objects to create headers
54+
const allKeys = new Set<string>()
55+
processedValues.forEach((obj: any) => {
56+
if (obj && typeof obj === 'object') {
57+
Object.keys(obj).forEach(key => allKeys.add(key))
58+
}
59+
})
60+
const headers = Array.from(allKeys)
61+
62+
// Then create rows with object values in the order of headers
63+
const rows = processedValues.map((obj: any) => {
64+
if (!obj || typeof obj !== 'object') {
65+
// Handle non-object items by creating an array with empty values
66+
return Array(headers.length).fill('')
67+
}
68+
return headers.map(key => {
69+
const value = obj[key]
70+
// Handle nested objects/arrays by converting to JSON string
71+
if (value !== null && typeof value === 'object') {
72+
return JSON.stringify(value)
73+
}
74+
return value === undefined ? '' : value
75+
})
76+
})
77+
78+
// Add headers as the first row, then add data rows
79+
processedValues = [headers, ...rows]
80+
}
81+
4782
const body: Record<string, any> = {
4883
majorDimension: params.majorDimension || 'ROWS',
49-
values: params.values || [],
84+
values: processedValues,
5085
}
5186

5287
// Only include range if it's provided

sim/tools/google_sheets/write.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,44 @@ export const writeTool: ToolConfig<GoogleSheetsToolParams, GoogleSheetsWriteResp
4444
'Content-Type': 'application/json',
4545
}),
4646
body: (params) => {
47+
let processedValues: any = params.values || []
48+
49+
// Handle array of objects
50+
if (Array.isArray(processedValues) && processedValues.length > 0 && typeof processedValues[0] === 'object' && !Array.isArray(processedValues[0])) {
51+
// It's an array of objects
52+
53+
// First, extract all unique keys from all objects to create headers
54+
const allKeys = new Set<string>()
55+
processedValues.forEach((obj: any) => {
56+
if (obj && typeof obj === 'object') {
57+
Object.keys(obj).forEach(key => allKeys.add(key))
58+
}
59+
})
60+
const headers = Array.from(allKeys)
61+
62+
// Then create rows with object values in the order of headers
63+
const rows = processedValues.map((obj: any) => {
64+
if (!obj || typeof obj !== 'object') {
65+
// Handle non-object items by creating an array with empty values
66+
return Array(headers.length).fill('')
67+
}
68+
return headers.map(key => {
69+
const value = obj[key]
70+
// Handle nested objects/arrays by converting to JSON string
71+
if (value !== null && typeof value === 'object') {
72+
return JSON.stringify(value)
73+
}
74+
return value === undefined ? '' : value
75+
})
76+
})
77+
78+
// Add headers as the first row, then add data rows
79+
processedValues = [headers, ...rows]
80+
}
81+
4782
const body: Record<string, any> = {
4883
majorDimension: params.majorDimension || 'ROWS',
49-
values: params.values || [],
84+
values: processedValues,
5085
}
5186

5287
// Only include range if it's provided

0 commit comments

Comments
 (0)