import { validateDatabaseIdentifier } from '@/lib/core/security/input-validation' import type { SupabaseGetRowParams, SupabaseGetRowResponse } from '@/tools/supabase/types' import { supabaseBaseUrl } from '@/tools/supabase/utils' import type { ToolConfig } from '@/tools/types' export const getRowTool: ToolConfig = { id: 'supabase_get_row', name: 'Supabase Get Row', description: 'Get a single row from a Supabase table based on filter criteria', version: '1.0.0', params: { projectId: { type: 'string', required: true, visibility: 'user-only', description: 'Your Supabase project ID (e.g., jdrkgepadsdopsntdlom)', }, table: { type: 'string', required: true, visibility: 'user-or-llm', description: 'The name of the Supabase table to query', }, schema: { type: 'string', required: false, visibility: 'user-or-llm', description: 'Database schema to query from (default: public). Use this to access tables in other schemas.', }, select: { type: 'string', required: false, visibility: 'user-or-llm', description: 'Columns to return (comma-separated). Defaults to * (all columns)', }, filter: { type: 'string', required: true, visibility: 'user-or-llm', description: 'PostgREST filter to find the specific row (e.g., "id=eq.123")', }, apiKey: { type: 'string', required: true, visibility: 'user-only', description: 'Your Supabase service role secret key', }, }, request: { url: (params) => { const tableValidation = validateDatabaseIdentifier(params.table, 'table') if (!tableValidation.isValid) throw new Error(tableValidation.error) const selectColumns = params.select?.trim() || '*' let url = `${supabaseBaseUrl(params.projectId)}/rest/v1/${encodeURIComponent(params.table)}?select=${encodeURIComponent(selectColumns)}` if (params.filter?.trim()) { url += `&${params.filter.trim()}` } url += `&limit=1` return url }, method: 'GET', headers: (params) => { const headers: Record = { apikey: params.apiKey, Authorization: `Bearer ${params.apiKey}`, } if (params.schema) { headers['Accept-Profile'] = params.schema } return headers }, }, transformResponse: async (response: Response) => { let data try { data = await response.json() } catch (parseError) { throw new Error(`Failed to parse Supabase response: ${parseError}`) } const rowFound = data.length > 0 const results = rowFound ? [data[0]] : [] return { success: true, output: { message: rowFound ? 'Successfully found 1 row' : 'No row found matching the criteria', results: results, }, error: undefined, } }, outputs: { message: { type: 'string', description: 'Operation status message' }, results: { type: 'array', description: 'Array containing the row data if found, empty array if not found', }, }, }