|
|
import { createQueryHook } from '@/hooks/use-query'; |
|
|
import { backendApi } from '@/lib/api-client'; |
|
|
import { pipedreamKeys } from './keys'; |
|
|
import type { |
|
|
PipedreamProfile, |
|
|
CreateProfileRequest, |
|
|
UpdateProfileRequest, |
|
|
ProfileConnectionResponse, |
|
|
ProfileConnectionsResponse |
|
|
} from '@/components/agents/pipedream/pipedream-types'; |
|
|
|
|
|
export interface CreateConnectionTokenRequest { |
|
|
app?: string; |
|
|
} |
|
|
|
|
|
export interface ConnectionTokenResponse { |
|
|
success: boolean; |
|
|
link?: string; |
|
|
token?: string; |
|
|
external_user_id: string; |
|
|
app?: string; |
|
|
expires_at?: string; |
|
|
error?: string; |
|
|
} |
|
|
|
|
|
export interface ConnectionResponse { |
|
|
success: boolean; |
|
|
connections: Connection[]; |
|
|
count: number; |
|
|
error?: string; |
|
|
} |
|
|
|
|
|
export interface Connection { |
|
|
id: string; |
|
|
app: string; |
|
|
name: string; |
|
|
status: 'connected' | 'disconnected' | 'error'; |
|
|
created_at: string; |
|
|
updated_at: string; |
|
|
[key: string]: any; |
|
|
} |
|
|
|
|
|
export interface PipedreamHealthCheckResponse { |
|
|
status: 'healthy' | 'unhealthy'; |
|
|
project_id: string; |
|
|
environment: string; |
|
|
has_access_token: boolean; |
|
|
error?: string; |
|
|
} |
|
|
|
|
|
export interface TriggerWorkflowRequest { |
|
|
workflow_id: string; |
|
|
payload: Record<string, any>; |
|
|
} |
|
|
|
|
|
export interface TriggerWorkflowResponse { |
|
|
success: boolean; |
|
|
workflow_id: string; |
|
|
run_id?: string; |
|
|
status?: string; |
|
|
error?: string; |
|
|
} |
|
|
|
|
|
export interface WorkflowRun { |
|
|
id: string; |
|
|
workflow_id: string; |
|
|
status: 'running' | 'completed' | 'failed' | 'cancelled'; |
|
|
started_at: string; |
|
|
completed_at?: string; |
|
|
error?: string; |
|
|
[key: string]: any; |
|
|
} |
|
|
|
|
|
export interface PipedreamConfigStatus { |
|
|
success: boolean; |
|
|
project_id: string; |
|
|
environment: string; |
|
|
has_client_id: boolean; |
|
|
has_client_secret: boolean; |
|
|
base_url: string; |
|
|
} |
|
|
|
|
|
export interface PipedreamApp { |
|
|
id: string; |
|
|
name: string; |
|
|
name_slug: string; |
|
|
auth_type: string; |
|
|
description: string; |
|
|
img_src: string; |
|
|
custom_fields_json: string; |
|
|
categories: string[]; |
|
|
featured_weight: number; |
|
|
connect: { |
|
|
allowed_domains: string[] | null; |
|
|
base_proxy_target_url: string; |
|
|
proxy_enabled: boolean; |
|
|
}; |
|
|
} |
|
|
|
|
|
export interface PipedreamAppResponse { |
|
|
success: boolean; |
|
|
apps: PipedreamApp[]; |
|
|
page_info: { |
|
|
total_count: number; |
|
|
count: number; |
|
|
has_more: boolean; |
|
|
start_cursor?: string; |
|
|
end_cursor?: string; |
|
|
}; |
|
|
total_count: number; |
|
|
error?: string; |
|
|
search_query?: string; |
|
|
} |
|
|
|
|
|
export interface PipedreamTool { |
|
|
name: string; |
|
|
description: string; |
|
|
inputSchema: any; |
|
|
} |
|
|
|
|
|
export interface PipedreamAppWithTools { |
|
|
app_name: string; |
|
|
app_slug: string; |
|
|
tools: PipedreamTool[]; |
|
|
tool_count: number; |
|
|
} |
|
|
|
|
|
export interface PipedreamToolsResponse { |
|
|
success: boolean; |
|
|
apps: PipedreamAppWithTools[]; |
|
|
total_apps: number; |
|
|
total_tools: number; |
|
|
user_id?: string; |
|
|
timestamp?: number; |
|
|
error?: string; |
|
|
} |
|
|
|
|
|
export interface AppIconResponse { |
|
|
success: boolean; |
|
|
app_slug: string; |
|
|
icon_url: string; |
|
|
} |
|
|
|
|
|
export const usePipedreamConnections = createQueryHook( |
|
|
pipedreamKeys.connections(), |
|
|
async (): Promise<ConnectionResponse> => { |
|
|
return await pipedreamApi.getConnections(); |
|
|
}, |
|
|
{ |
|
|
staleTime: 10 * 60 * 1000, |
|
|
gcTime: 15 * 60 * 1000, |
|
|
refetchOnWindowFocus: false, |
|
|
refetchOnMount: false, |
|
|
refetchInterval: false, |
|
|
} |
|
|
); |
|
|
|
|
|
export const pipedreamApi = { |
|
|
async createConnectionToken(request: CreateConnectionTokenRequest = {}): Promise<ConnectionTokenResponse> { |
|
|
const result = await backendApi.post<ConnectionTokenResponse>( |
|
|
'/pipedream/connection-token', |
|
|
request, |
|
|
{ |
|
|
errorContext: { operation: 'create connection token', resource: 'Pipedream connection' }, |
|
|
} |
|
|
); |
|
|
|
|
|
if (!result.success) { |
|
|
throw new Error(result.error?.message || 'Failed to create connection token'); |
|
|
} |
|
|
|
|
|
return result.data!; |
|
|
}, |
|
|
|
|
|
async getConnections(): Promise<ConnectionResponse> { |
|
|
const result = await backendApi.get<ConnectionResponse>( |
|
|
'/pipedream/connections', |
|
|
{ |
|
|
errorContext: { operation: 'load connections', resource: 'Pipedream connections' }, |
|
|
} |
|
|
); |
|
|
|
|
|
if (!result.success) { |
|
|
throw new Error(result.error?.message || 'Failed to get connections'); |
|
|
} |
|
|
|
|
|
return result.data!; |
|
|
}, |
|
|
|
|
|
async getApps(after?: string, search?: string): Promise<PipedreamAppResponse> { |
|
|
const params = new URLSearchParams(); |
|
|
|
|
|
if (after) { |
|
|
params.append('after', after); |
|
|
} |
|
|
|
|
|
if (search) { |
|
|
params.append('q', search); |
|
|
} |
|
|
|
|
|
const result = await backendApi.get<PipedreamAppResponse>( |
|
|
`/pipedream/apps${params.toString() ? `?${params.toString()}` : ''}`, |
|
|
{ |
|
|
errorContext: { operation: 'load apps', resource: 'Pipedream apps' }, |
|
|
} |
|
|
); |
|
|
|
|
|
if (!result.success) { |
|
|
throw new Error(result.error?.message || 'Failed to get apps'); |
|
|
} |
|
|
const data = result.data!; |
|
|
if (!data.success && data.error) { |
|
|
throw new Error(data.error); |
|
|
} |
|
|
return data; |
|
|
}, |
|
|
|
|
|
async getPopularApps(): Promise<PipedreamAppResponse> { |
|
|
const result = await backendApi.get<PipedreamAppResponse>( |
|
|
'/pipedream/apps/popular', |
|
|
{ |
|
|
errorContext: { operation: 'load popular apps', resource: 'Pipedream popular apps' }, |
|
|
} |
|
|
); |
|
|
console.log('result', result); |
|
|
if (!result.success) { |
|
|
throw new Error(result.error?.message || 'Failed to get popular apps'); |
|
|
} |
|
|
const data = result.data!; |
|
|
if (!data.success && data.error) { |
|
|
throw new Error(data.error); |
|
|
} |
|
|
return data; |
|
|
}, |
|
|
|
|
|
async getAvailableTools(): Promise<PipedreamToolsResponse> { |
|
|
const result = await backendApi.get<PipedreamToolsResponse>( |
|
|
'/pipedream/mcp/available-tools', |
|
|
{ |
|
|
errorContext: { operation: 'load available tools', resource: 'Pipedream tools' }, |
|
|
} |
|
|
); |
|
|
if (!result.success) { |
|
|
throw new Error(result.error?.message || 'Failed to get available tools'); |
|
|
} |
|
|
|
|
|
return result.data!; |
|
|
}, |
|
|
|
|
|
async healthCheck(): Promise<PipedreamHealthCheckResponse> { |
|
|
const result = await backendApi.get<PipedreamHealthCheckResponse>( |
|
|
'/pipedream/health', |
|
|
{ |
|
|
errorContext: { operation: 'health check', resource: 'Pipedream service' }, |
|
|
} |
|
|
); |
|
|
|
|
|
if (!result.success) { |
|
|
throw new Error(result.error?.message || 'Health check failed'); |
|
|
} |
|
|
|
|
|
return result.data!; |
|
|
}, |
|
|
|
|
|
async discoverMCPServers(externalUserId: string, appSlug?: string): Promise<any> { |
|
|
const request = { |
|
|
external_user_id: externalUserId, |
|
|
app_slug: appSlug |
|
|
}; |
|
|
|
|
|
const result = await backendApi.post<any>( |
|
|
'/pipedream/mcp/discover-profile', |
|
|
request, |
|
|
{ |
|
|
errorContext: { operation: 'discover MCP servers', resource: 'Pipedream MCP' }, |
|
|
} |
|
|
); |
|
|
|
|
|
if (!result.success) { |
|
|
throw new Error(result.error?.message || 'Failed to discover MCP servers'); |
|
|
} |
|
|
|
|
|
return result.data?.mcp_servers || []; |
|
|
}, |
|
|
|
|
|
|
|
|
async createProfile(request: CreateProfileRequest): Promise<PipedreamProfile> { |
|
|
const result = await backendApi.post<PipedreamProfile>( |
|
|
'/pipedream/profiles', |
|
|
request, |
|
|
{ |
|
|
errorContext: { operation: 'create profile', resource: 'Pipedream credential profile' }, |
|
|
} |
|
|
); |
|
|
|
|
|
if (!result.success) { |
|
|
throw new Error(result.error?.message || 'Failed to create profile'); |
|
|
} |
|
|
|
|
|
return result.data!; |
|
|
}, |
|
|
|
|
|
async getProfiles(params?: { app_slug?: string; is_active?: boolean }): Promise<PipedreamProfile[]> { |
|
|
const queryParams = new URLSearchParams(); |
|
|
if (params?.app_slug) queryParams.append('app_slug', params.app_slug); |
|
|
if (params?.is_active !== undefined) queryParams.append('is_active', params.is_active.toString()); |
|
|
|
|
|
const result = await backendApi.get<PipedreamProfile[]>( |
|
|
`/pipedream/profiles${queryParams.toString() ? `?${queryParams.toString()}` : ''}`, |
|
|
{ |
|
|
errorContext: { operation: 'get profiles', resource: 'Pipedream credential profiles' }, |
|
|
} |
|
|
); |
|
|
|
|
|
if (!result.success) { |
|
|
throw new Error(result.error?.message || 'Failed to get profiles'); |
|
|
} |
|
|
|
|
|
return result.data!; |
|
|
}, |
|
|
|
|
|
async getProfile(profileId: string): Promise<PipedreamProfile> { |
|
|
const result = await backendApi.get<PipedreamProfile>( |
|
|
`/pipedream/profiles/${profileId}`, |
|
|
{ |
|
|
errorContext: { operation: 'get profile', resource: 'Pipedream credential profile' }, |
|
|
} |
|
|
); |
|
|
|
|
|
if (!result.success) { |
|
|
throw new Error(result.error?.message || 'Failed to get profile'); |
|
|
} |
|
|
|
|
|
return result.data!; |
|
|
}, |
|
|
|
|
|
async updateProfile(profileId: string, request: UpdateProfileRequest): Promise<PipedreamProfile> { |
|
|
const result = await backendApi.put<PipedreamProfile>( |
|
|
`/pipedream/profiles/${profileId}`, |
|
|
request, |
|
|
{ |
|
|
errorContext: { operation: 'update profile', resource: 'Pipedream credential profile' }, |
|
|
} |
|
|
); |
|
|
|
|
|
if (!result.success) { |
|
|
throw new Error(result.error?.message || 'Failed to update profile'); |
|
|
} |
|
|
|
|
|
return result.data!; |
|
|
}, |
|
|
|
|
|
async deleteProfile(profileId: string): Promise<void> { |
|
|
const result = await backendApi.delete( |
|
|
`/pipedream/profiles/${profileId}`, |
|
|
{ |
|
|
errorContext: { operation: 'delete profile', resource: 'Pipedream credential profile' }, |
|
|
} |
|
|
); |
|
|
|
|
|
if (!result.success) { |
|
|
throw new Error(result.error?.message || 'Failed to delete profile'); |
|
|
} |
|
|
}, |
|
|
|
|
|
async connectProfile(profileId: string, app?: string): Promise<ProfileConnectionResponse> { |
|
|
const queryParams = app ? `?app=${encodeURIComponent(app)}` : ''; |
|
|
const result = await backendApi.post<ProfileConnectionResponse>( |
|
|
`/pipedream/profiles/${profileId}/connect${queryParams}`, |
|
|
{}, |
|
|
{ |
|
|
errorContext: { operation: 'connect profile', resource: 'Pipedream credential profile' }, |
|
|
} |
|
|
); |
|
|
|
|
|
if (!result.success) { |
|
|
throw new Error(result.error?.message || 'Failed to connect profile'); |
|
|
} |
|
|
|
|
|
return result.data!; |
|
|
}, |
|
|
|
|
|
async getProfileConnections(profileId: string): Promise<ProfileConnectionsResponse> { |
|
|
const result = await backendApi.get<ProfileConnectionsResponse>( |
|
|
`/pipedream/profiles/${profileId}/connections`, |
|
|
{ |
|
|
errorContext: { operation: 'get profile connections', resource: 'Pipedream profile connections' }, |
|
|
} |
|
|
); |
|
|
|
|
|
if (!result.success) { |
|
|
throw new Error(result.error?.message || 'Failed to get profile connections'); |
|
|
} |
|
|
|
|
|
return result.data!; |
|
|
}, |
|
|
|
|
|
async getAppIcon(appSlug: string): Promise<AppIconResponse> { |
|
|
const result = await backendApi.get<AppIconResponse>( |
|
|
`/pipedream/apps/${appSlug}/icon`, |
|
|
{ |
|
|
errorContext: { operation: 'get app icon', resource: 'Pipedream app icon' }, |
|
|
} |
|
|
); |
|
|
if (!result.success) { |
|
|
throw new Error(result.error?.message || 'Failed to get app icon'); |
|
|
} |
|
|
return result.data!; |
|
|
}, |
|
|
}; |