mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-22 21:38:05 -05:00
updates
This commit is contained in:
@@ -64,7 +64,14 @@ export async function GET(
|
||||
id: table.id,
|
||||
name: table.name,
|
||||
description: table.description,
|
||||
schema: table.schema,
|
||||
schema: {
|
||||
columns: (table.schema as any).columns.map((col: any) => ({
|
||||
name: col.name,
|
||||
type: col.type,
|
||||
required: col.required ?? false,
|
||||
unique: col.unique ?? false,
|
||||
})),
|
||||
},
|
||||
rowCount: table.rowCount,
|
||||
maxRows: table.maxRows,
|
||||
createdAt: table.createdAt.toISOString(),
|
||||
|
||||
@@ -172,6 +172,16 @@ export async function POST(request: NextRequest) {
|
||||
)
|
||||
}
|
||||
|
||||
// Normalize schema to ensure all fields have explicit defaults
|
||||
const normalizedSchema = {
|
||||
columns: params.schema.columns.map((col) => ({
|
||||
name: col.name,
|
||||
type: col.type,
|
||||
required: col.required ?? false,
|
||||
unique: col.unique ?? false,
|
||||
})),
|
||||
}
|
||||
|
||||
// Create table
|
||||
const tableId = `tbl_${crypto.randomUUID().replace(/-/g, '')}`
|
||||
const now = new Date()
|
||||
@@ -183,7 +193,7 @@ export async function POST(request: NextRequest) {
|
||||
workspaceId: params.workspaceId,
|
||||
name: params.name,
|
||||
description: params.description,
|
||||
schema: params.schema,
|
||||
schema: normalizedSchema,
|
||||
maxRows: TABLE_LIMITS.MAX_ROWS_PER_TABLE,
|
||||
rowCount: 0,
|
||||
createdBy: authResult.userId,
|
||||
@@ -279,6 +289,14 @@ export async function GET(request: NextRequest) {
|
||||
return NextResponse.json({
|
||||
tables: tables.map((t) => ({
|
||||
...t,
|
||||
schema: {
|
||||
columns: (t.schema as any).columns.map((col: any) => ({
|
||||
name: col.name,
|
||||
type: col.type,
|
||||
required: col.required ?? false,
|
||||
unique: col.unique ?? false,
|
||||
})),
|
||||
},
|
||||
createdAt: t.createdAt.toISOString(),
|
||||
updatedAt: t.updatedAt.toISOString(),
|
||||
})),
|
||||
|
||||
@@ -28,6 +28,7 @@ export const TableBlock: BlockConfig<TableQueryResponse> = {
|
||||
{ label: 'Update Row by ID', id: 'updateRow' },
|
||||
{ label: 'Delete Row by ID', id: 'deleteRow' },
|
||||
{ label: 'Get Row by ID', id: 'getRow' },
|
||||
{ label: 'Get Schema', id: 'getSchema' },
|
||||
],
|
||||
value: () => 'queryRows',
|
||||
},
|
||||
@@ -449,6 +450,7 @@ Return ONLY the sort JSON:`,
|
||||
'table_delete_rows_by_filter',
|
||||
'table_query_rows',
|
||||
'table_get_row',
|
||||
'table_get_schema',
|
||||
],
|
||||
config: {
|
||||
tool: (params) => {
|
||||
@@ -462,6 +464,7 @@ Return ONLY the sort JSON:`,
|
||||
deleteRowsByFilter: 'table_delete_rows_by_filter',
|
||||
queryRows: 'table_query_rows',
|
||||
getRow: 'table_get_row',
|
||||
getSchema: 'table_get_schema',
|
||||
}
|
||||
return toolMap[params.operation] || 'table_query_rows'
|
||||
},
|
||||
@@ -583,6 +586,13 @@ Return ONLY the sort JSON:`,
|
||||
}
|
||||
}
|
||||
|
||||
// Get Schema
|
||||
if (operation === 'getSchema') {
|
||||
return {
|
||||
tableId: rest.tableId,
|
||||
}
|
||||
}
|
||||
|
||||
// Query Rows
|
||||
if (operation === 'queryRows') {
|
||||
let filter: any
|
||||
@@ -695,6 +705,16 @@ Return ONLY the sort JSON:`,
|
||||
description: 'IDs of deleted rows',
|
||||
condition: { field: 'operation', value: 'deleteRowsByFilter' },
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Table name',
|
||||
condition: { field: 'operation', value: 'getSchema' },
|
||||
},
|
||||
columns: {
|
||||
type: 'array',
|
||||
description: 'Column definitions',
|
||||
condition: { field: 'operation', value: 'getSchema' },
|
||||
},
|
||||
message: { type: 'string', description: 'Operation status message' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1376,6 +1376,7 @@ import {
|
||||
tableDeleteRowsByFilterTool,
|
||||
tableDeleteRowTool,
|
||||
tableGetRowTool,
|
||||
tableGetSchemaTool,
|
||||
tableInsertRowTool,
|
||||
tableListTool,
|
||||
tableQueryRowsTool,
|
||||
@@ -2726,6 +2727,7 @@ export const tools: Record<string, ToolConfig> = {
|
||||
table_delete_rows_by_filter: tableDeleteRowsByFilterTool,
|
||||
table_query_rows: tableQueryRowsTool,
|
||||
table_get_row: tableGetRowTool,
|
||||
table_get_schema: tableGetSchemaTool,
|
||||
mailchimp_get_audiences: mailchimpGetAudiencesTool,
|
||||
mailchimp_get_audience: mailchimpGetAudienceTool,
|
||||
mailchimp_create_audience: mailchimpCreateAudienceTool,
|
||||
|
||||
@@ -47,33 +47,6 @@ export const tableBatchInsertRowsTool: ToolConfig<
|
||||
transformResponse: async (response): Promise<TableBatchInsertResponse> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
let errorMessage = data.error || 'Failed to batch insert rows'
|
||||
|
||||
// Include details if present
|
||||
if (data.details) {
|
||||
if (Array.isArray(data.details) && data.details.length > 0) {
|
||||
// Check if details is array of error objects with row numbers
|
||||
if (typeof data.details[0] === 'object' && 'row' in data.details[0]) {
|
||||
const errorSummary = data.details
|
||||
.map((detail: { row: number; errors: string[] }) => {
|
||||
const rowErrors = detail.errors.join(', ')
|
||||
return `Row ${detail.row}: ${rowErrors}`
|
||||
})
|
||||
.join('; ')
|
||||
errorMessage = `${errorMessage}: ${errorSummary}`
|
||||
} else {
|
||||
// Simple array of strings
|
||||
errorMessage = `${errorMessage}: ${data.details.join('; ')}`
|
||||
}
|
||||
} else if (typeof data.details === 'string') {
|
||||
errorMessage = `${errorMessage}: ${data.details}`
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(errorMessage)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
|
||||
@@ -52,10 +52,6 @@ export const tableCreateTool: ToolConfig<TableCreateParams, TableCreateResponse>
|
||||
transformResponse: async (response): Promise<TableCreateResponse> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to create table')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
|
||||
@@ -43,10 +43,6 @@ export const tableDeleteRowTool: ToolConfig<TableRowDeleteParams, TableDeleteRes
|
||||
transformResponse: async (response): Promise<TableDeleteResponse> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to delete row')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
|
||||
@@ -55,10 +55,6 @@ export const tableDeleteRowsByFilterTool: ToolConfig<
|
||||
transformResponse: async (response): Promise<TableBulkOperationResponse> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to delete rows')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
|
||||
@@ -40,10 +40,6 @@ export const tableGetRowTool: ToolConfig<TableRowGetParams, TableRowResponse> =
|
||||
transformResponse: async (response): Promise<TableRowResponse> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to get row')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
|
||||
53
apps/sim/tools/table/get-schema.ts
Normal file
53
apps/sim/tools/table/get-schema.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { TableGetSchemaParams, TableGetSchemaResponse } from './types'
|
||||
|
||||
export const tableGetSchemaTool: ToolConfig<TableGetSchemaParams, TableGetSchemaResponse> = {
|
||||
id: 'table_get_schema',
|
||||
name: 'Get Schema',
|
||||
description: 'Get the schema configuration of a table',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
tableId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
description: 'Table ID',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params: any) => {
|
||||
const workspaceId = params._context?.workspaceId
|
||||
if (!workspaceId) {
|
||||
throw new Error('workspaceId is required in execution context')
|
||||
}
|
||||
|
||||
return `/api/table/${params.tableId}?workspaceId=${encodeURIComponent(workspaceId)}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response): Promise<TableGetSchemaResponse> => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
name: data.table.name,
|
||||
columns: data.table.schema.columns,
|
||||
message: 'Schema retrieved successfully',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Whether schema was retrieved' },
|
||||
name: { type: 'string', description: 'Table name' },
|
||||
columns: { type: 'array', description: 'Column definitions' },
|
||||
message: { type: 'string', description: 'Status message' },
|
||||
},
|
||||
}
|
||||
@@ -3,6 +3,7 @@ export * from './create'
|
||||
export * from './delete-row'
|
||||
export * from './delete-rows-by-filter'
|
||||
export * from './get-row'
|
||||
export * from './get-schema'
|
||||
export * from './insert-row'
|
||||
export * from './list'
|
||||
export * from './query-rows'
|
||||
|
||||
@@ -44,22 +44,6 @@ export const tableInsertRowTool: ToolConfig<TableRowInsertParams, TableRowRespon
|
||||
transformResponse: async (response): Promise<TableRowResponse> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
let errorMessage = data.error || 'Failed to insert row'
|
||||
|
||||
// Include details array if present
|
||||
if (data.details) {
|
||||
if (Array.isArray(data.details) && data.details.length > 0) {
|
||||
const detailsStr = data.details.join('; ')
|
||||
errorMessage = `${errorMessage}: ${detailsStr}`
|
||||
} else if (typeof data.details === 'string') {
|
||||
errorMessage = `${errorMessage}: ${data.details}`
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(errorMessage)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
|
||||
@@ -26,10 +26,6 @@ export const tableListTool: ToolConfig<TableListParams, TableListResponse> = {
|
||||
transformResponse: async (response): Promise<TableListResponse> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to list tables')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
|
||||
@@ -76,10 +76,6 @@ export const tableQueryRowsTool: ToolConfig<TableRowQueryParams, TableQueryRespo
|
||||
transformResponse: async (response): Promise<TableQueryResponse> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to query rows')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
|
||||
@@ -185,3 +185,16 @@ export interface TableBulkOperationResponse extends ToolResponse {
|
||||
message: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface TableGetSchemaParams extends ToolParamsWithContext {
|
||||
tableId: string
|
||||
workspaceId?: string
|
||||
}
|
||||
|
||||
export interface TableGetSchemaResponse extends ToolResponse {
|
||||
output: {
|
||||
name: string
|
||||
columns: ColumnDefinition[]
|
||||
message: string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,22 +50,6 @@ export const tableUpdateRowTool: ToolConfig<TableRowUpdateParams, TableRowRespon
|
||||
transformResponse: async (response): Promise<TableRowResponse> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
let errorMessage = data.error || 'Failed to update row'
|
||||
|
||||
// Include details array if present
|
||||
if (data.details) {
|
||||
if (Array.isArray(data.details) && data.details.length > 0) {
|
||||
const detailsStr = data.details.join('; ')
|
||||
errorMessage = `${errorMessage}: ${detailsStr}`
|
||||
} else if (typeof data.details === 'string') {
|
||||
errorMessage = `${errorMessage}: ${data.details}`
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(errorMessage)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
|
||||
@@ -62,22 +62,6 @@ export const tableUpdateRowsByFilterTool: ToolConfig<
|
||||
transformResponse: async (response): Promise<TableBulkOperationResponse> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
let errorMessage = data.error || 'Failed to update rows'
|
||||
|
||||
// Include details array if present
|
||||
if (data.details) {
|
||||
if (Array.isArray(data.details) && data.details.length > 0) {
|
||||
const detailsStr = data.details.join('; ')
|
||||
errorMessage = `${errorMessage}: ${detailsStr}`
|
||||
} else if (typeof data.details === 'string') {
|
||||
errorMessage = `${errorMessage}: ${data.details}`
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(errorMessage)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
|
||||
@@ -49,22 +49,6 @@ export const tableUpsertRowTool: ToolConfig<TableRowInsertParams, TableUpsertRes
|
||||
transformResponse: async (response): Promise<TableUpsertResponse> => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
let errorMessage = data.error || 'Failed to upsert row'
|
||||
|
||||
// Include details array if present
|
||||
if (data.details) {
|
||||
if (Array.isArray(data.details) && data.details.length > 0) {
|
||||
const detailsStr = data.details.join('; ')
|
||||
errorMessage = `${errorMessage}: ${detailsStr}`
|
||||
} else if (typeof data.details === 'string') {
|
||||
errorMessage = `${errorMessage}: ${data.details}`
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(errorMessage)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
|
||||
Reference in New Issue
Block a user