From 454f98b7d0753631ae143aa3bf63d12bbf90ba2e Mon Sep 17 00:00:00 2001 From: Saxon Fletcher Date: Thu, 6 Feb 2025 09:25:19 +1000 Subject: [PATCH] deploy edge function mutaton --- .../edge-functions-deploy-mutation.ts | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 apps/studio/data/edge-functions/edge-functions-deploy-mutation.ts diff --git a/apps/studio/data/edge-functions/edge-functions-deploy-mutation.ts b/apps/studio/data/edge-functions/edge-functions-deploy-mutation.ts new file mode 100644 index 00000000000..fed2edda2bc --- /dev/null +++ b/apps/studio/data/edge-functions/edge-functions-deploy-mutation.ts @@ -0,0 +1,87 @@ +import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query' +import { toast } from 'sonner' + +import { handleError, constructHeaders } from 'data/fetchers' +import { API_URL } from 'lib/constants' +import type { ResponseError } from 'types' +import { edgeFunctionsKeys } from './keys' + +export type EdgeFunctionsDeployVariables = { + projectRef: string + metadata: { + entrypoint_path?: string + import_map_path?: string + name?: string + static_patterns?: string[] + verify_jwt?: boolean + } + files: { name: string; content: string }[] +} + +export async function deployEdgeFunction({ + projectRef, + metadata, + files, +}: EdgeFunctionsDeployVariables) { + if (!projectRef) throw new Error('projectRef is required') + + const formData = new FormData() + formData.append('metadata', JSON.stringify(metadata)) + + files.forEach((file) => { + const blob = new Blob([file.content], { type: 'text/plain' }) + formData.append('file', blob, file.name) + }) + + const response = await fetch( + `${API_URL?.replace('/platform', '')}/v1/projects/${projectRef}/functions/deploy?slug=${metadata.name}`, + { + method: 'POST', + body: formData, + headers: await constructHeaders(), + credentials: 'include', + referrerPolicy: 'no-referrer-when-downgrade', + } + ) + + const result = await response.json() + if (response.ok) { + return result + } + + result.code = response.status + result.requestId = response.headers.get('X-Request-Id') + handleError(result) +} + +type EdgeFunctionsDeployData = Awaited> + +export const useEdgeFunctionDeployMutation = ({ + onSuccess, + onError, + ...options +}: Omit< + UseMutationOptions, + 'mutationFn' +> = {}) => { + const queryClient = useQueryClient() + + return useMutation( + (vars) => deployEdgeFunction(vars), + { + async onSuccess(data, variables, context) { + const { projectRef } = variables + await Promise.all([queryClient.invalidateQueries(edgeFunctionsKeys.list(projectRef))]) + await onSuccess?.(data, variables, context) + }, + async onError(data, variables, context) { + if (onError === undefined) { + toast.error(`Failed to deploy edge function: ${data.message}`) + } else { + onError(data, variables, context) + } + }, + ...options, + } + ) +}