Files
supabase/apps/studio/data/logs/get-unified-logs.ts
Ivan Vasilov 8b657165b5 chore: Migrate to use custom type for ReactQuery queries and mutations (#40073)
* Add custom types for queries, mutations and infinite queries.

* Migrate all queries to use the new type.

* Migrate all infinite queries to useCustomInfiniteQueryOptions.

* Migrate all mutations to use useCustomMutationOptions.

* Add type to all imports in `types` folder.
2025-11-03 13:18:13 +01:00

90 lines
2.9 KiB
TypeScript

import { useMutation } from '@tanstack/react-query'
import { toast } from 'sonner'
import { getUnifiedLogsQuery } from 'components/interfaces/UnifiedLogs/UnifiedLogs.queries'
import { QuerySearchParamsType } from 'components/interfaces/UnifiedLogs/UnifiedLogs.types'
import { handleError, post } from 'data/fetchers'
import type { ResponseError, UseCustomMutationOptions } from 'types'
import { getUnifiedLogsISOStartEnd } from './unified-logs-infinite-query'
export type getUnifiedLogsVariables = {
projectRef: string
search: QuerySearchParamsType
limit: number
hoursAgo?: number
}
// [Joshen] Mainly for retrieving logs on demand for downloading
export async function retrieveUnifiedLogs({
projectRef,
search,
limit,
hoursAgo,
}: getUnifiedLogsVariables) {
if (typeof projectRef === 'undefined')
throw new Error('projectRef is required for retrieveUnifiedLogs')
const { isoTimestampStart, isoTimestampEnd } = getUnifiedLogsISOStartEnd(search, hoursAgo)
const sql = `${getUnifiedLogsQuery(search)} ORDER BY timestamp DESC, id DESC LIMIT ${limit}`
const { data, error } = await post(`/platform/projects/{ref}/analytics/endpoints/logs.all`, {
params: { path: { ref: projectRef } },
body: { iso_timestamp_start: isoTimestampStart, iso_timestamp_end: isoTimestampEnd, sql },
})
if (error) handleError(error)
const resultData = data?.result ?? []
const result = resultData.map((row: any) => {
const date = new Date(Number(row.timestamp) / 1000)
return {
id: row.id,
date,
timestamp: row.timestamp,
level: row.level,
status: row.status || 200,
method: row.method,
host: row.host,
pathname: (row.url || '').replace(/^https?:\/\/[^\/]+/, '') || row.pathname || '',
event_message: row.event_message || row.body || '',
headers:
typeof row.headers === 'string' ? JSON.parse(row.headers || '{}') : row.headers || {},
regions: row.region ? [row.region] : [],
log_type: row.log_type || '',
latency: row.latency || 0,
log_count: row.log_count || null,
logs: row.logs || [],
auth_user: row.auth_user || null,
}
})
return result
}
type LogDrainCreateData = Awaited<ReturnType<typeof retrieveUnifiedLogs>>
export const useGetUnifiedLogsMutation = ({
onSuccess,
onError,
...options
}: Omit<
UseCustomMutationOptions<LogDrainCreateData, ResponseError, getUnifiedLogsVariables>,
'mutationFn'
> = {}) => {
return useMutation<LogDrainCreateData, ResponseError, getUnifiedLogsVariables>({
mutationFn: (vars) => retrieveUnifiedLogs(vars),
async onSuccess(data, variables, context) {
await onSuccess?.(data, variables, context)
},
async onError(data, variables, context) {
if (onError === undefined) {
toast.error(`Failed to retrieve logs: ${data.message}`)
} else {
onError(data, variables, context)
}
},
...options,
})
}