Files
supabase/apps/studio/data/replication/validate-destination-mutation.ts
Riccardo Busetti d795240928 feat(etl): Add integration with new validation endpoint (#41731)
* feat(etl): Add integration with new validation endpoint

* Fix

* Fix

* Fix

* Fix

* UI nudges + clean up + refactors

* Fix TS

* Sort issues

* Small improvement

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-01-07 00:32:08 +08:00

87 lines
2.7 KiB
TypeScript

import { useMutation } from '@tanstack/react-query'
import type { components } from 'api-types'
import { handleError, post } from 'data/fetchers'
import type { ResponseError, UseCustomMutationOptions } from 'types'
import { DestinationConfig } from './create-destination-pipeline-mutation'
type ValidateDestinationParams = {
projectRef: string
destinationConfig: DestinationConfig
}
type ValidateDestinationResponse = components['schemas']['ValidateDestinationResponse']
export type ValidationFailure = ValidateDestinationResponse['validation_failures'][number]
async function validateDestination(
{ projectRef, destinationConfig }: ValidateDestinationParams,
signal?: AbortSignal
): Promise<ValidateDestinationResponse> {
if (!projectRef) throw new Error('projectRef is required')
// Build destination_config based on the type
let config: components['schemas']['ValidateReplicationDestinationBody']['config']
if ('bigQuery' in destinationConfig) {
const { projectId, datasetId, serviceAccountKey, maxStalenessMins } = destinationConfig.bigQuery
config = {
big_query: {
project_id: projectId,
dataset_id: datasetId,
service_account_key: serviceAccountKey,
...(maxStalenessMins !== undefined ? { max_staleness_mins: maxStalenessMins } : {}),
},
}
} else if ('iceberg' in destinationConfig) {
const {
projectRef: icebergProjectRef,
namespace,
warehouseName,
catalogToken,
s3AccessKeyId,
s3SecretAccessKey,
s3Region,
} = destinationConfig.iceberg
config = {
iceberg: {
supabase: {
namespace,
project_ref: icebergProjectRef,
warehouse_name: warehouseName,
catalog_token: catalogToken,
s3_access_key_id: s3AccessKeyId,
s3_secret_access_key: s3SecretAccessKey,
s3_region: s3Region,
},
},
}
} else {
throw new Error('Invalid destination config: must specify either bigQuery or iceberg')
}
const { data, error } = await post('/platform/replication/{ref}/destinations/validate', {
params: { path: { ref: projectRef } },
body: { config },
signal,
})
if (error) handleError(error)
return data as ValidateDestinationResponse
}
type ValidateDestinationData = Awaited<ReturnType<typeof validateDestination>>
export const useValidateDestinationMutation = (
options?: Omit<
UseCustomMutationOptions<ValidateDestinationData, ResponseError, ValidateDestinationParams>,
'mutationFn'
>
) => {
return useMutation<ValidateDestinationData, ResponseError, ValidateDestinationParams>({
mutationFn: (vars) => validateDestination(vars),
...options,
})
}