import axios, { AxiosError, AxiosResponse } from 'axios' import { ref } from 'vue' import { COMFY_API_BASE_URL } from '@/config/comfyApi' import type { components, operations } from '@/types/comfyRegistryTypes' import { isAbortError } from '@/utils/typeGuardUtil' const releaseApiClient = axios.create({ baseURL: COMFY_API_BASE_URL, headers: { 'Content-Type': 'application/json' } }) // Use generated types from OpenAPI spec export type ReleaseNote = components['schemas']['ReleaseNote'] export type GetReleasesParams = operations['getReleaseNotes']['parameters']['query'] // Use generated error response type export type ErrorResponse = components['schemas']['ErrorResponse'] // Release service for fetching release notes export const useReleaseService = () => { const isLoading = ref(false) const error = ref(null) // No transformation needed - API response matches the generated type // Handle API errors with context const handleApiError = ( err: unknown, context: string, routeSpecificErrors?: Record ): string => { if (!axios.isAxiosError(err)) return err instanceof Error ? `${context}: ${err.message}` : `${context}: Unknown error occurred` const axiosError = err as AxiosError if (axiosError.response) { const { status, data } = axiosError.response if (routeSpecificErrors && routeSpecificErrors[status]) return routeSpecificErrors[status] switch (status) { case 400: return `Bad request: ${data?.message || 'Invalid input'}` case 401: return 'Unauthorized: Authentication required' case 403: return `Forbidden: ${data?.message || 'Access denied'}` case 404: return `Not found: ${data?.message || 'Resource not found'}` case 500: return `Server error: ${data?.message || 'Internal server error'}` default: return `${context}: ${data?.message || axiosError.message}` } } return `${context}: ${axiosError.message}` } // Execute API request with error handling const executeApiRequest = async ( apiCall: () => Promise>, errorContext: string, routeSpecificErrors?: Record ): Promise => { isLoading.value = true error.value = null try { const response = await apiCall() return response.data } catch (err) { // Don't treat cancellations as errors if (isAbortError(err)) return null error.value = handleApiError(err, errorContext, routeSpecificErrors) return null } finally { isLoading.value = false } } // Fetch release notes from API const getReleases = async ( params: GetReleasesParams, signal?: AbortSignal ): Promise => { const endpoint = '/releases' const errorContext = 'Failed to get releases' const routeSpecificErrors = { 400: 'Invalid project or version parameter' } const apiResponse = await executeApiRequest( () => releaseApiClient.get(endpoint, { params, signal }), errorContext, routeSpecificErrors ) return apiResponse } return { isLoading, error, getReleases } }