import { PermissionAction } from '@supabase/shared-types/out/constants' import clsx from 'clsx' import { useParams } from 'common' import dayjs from 'dayjs' import { ExternalLink, Maximize2, Minimize2, Terminal } from 'lucide-react' import Link from 'next/link' import { useRouter } from 'next/router' import { useEffect, useMemo, useState } from 'react' import toast from 'react-hot-toast' import { ButtonTooltip } from 'components/ui/ButtonTooltip' import { FormActions } from 'components/ui/Forms/FormActions' import { FormHeader } from 'components/ui/Forms/FormHeader' import { FormPanel } from 'components/ui/Forms/FormPanel' import { FormSection, FormSectionContent, FormSectionLabel } from 'components/ui/Forms/FormSection' import { useProjectApiQuery } from 'data/config/project-api-query' import { useCustomDomainsQuery } from 'data/custom-domains/custom-domains-query' import { useEdgeFunctionQuery } from 'data/edge-functions/edge-function-query' import { useEdgeFunctionDeleteMutation } from 'data/edge-functions/edge-functions-delete-mutation' import { useEdgeFunctionUpdateMutation } from 'data/edge-functions/edge-functions-update-mutation' import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' import { AlertDescription_Shadcn_, AlertTitle_Shadcn_, Alert_Shadcn_, Button, CriticalIcon, Form, Input, Modal, Toggle, } from 'ui' import CommandRender from '../CommandRender' import { generateCLICommands } from './EdgeFunctionDetails.utils' const EdgeFunctionDetails = () => { const router = useRouter() const { ref: projectRef, functionSlug } = useParams() const [showDeleteModal, setShowDeleteModal] = useState(false) const [showInstructions, setShowInstructions] = useState(false) const { data: settings } = useProjectApiQuery({ projectRef }) const { data: customDomainData } = useCustomDomainsQuery({ projectRef }) const { data: selectedFunction } = useEdgeFunctionQuery({ projectRef, slug: functionSlug }) const { mutate: updateEdgeFunction, isLoading: isUpdating } = useEdgeFunctionUpdateMutation() const { mutate: deleteEdgeFunction, isLoading: isDeleting } = useEdgeFunctionDeleteMutation({ onSuccess: () => { toast.success(`Successfully deleted "${selectedFunction?.name}"`) router.push(`/project/${projectRef}/functions`) }, }) const formId = 'edge-function-update-form' const canUpdateEdgeFunction = useCheckPermissions(PermissionAction.FUNCTIONS_WRITE, '*') // Get the API service const apiService = settings?.autoApiService const anonKey = apiService?.defaultApiKey ?? '[YOUR ANON KEY]' const endpoint = apiService?.app_config.endpoint ?? '' const functionUrl = customDomainData?.customDomain?.status === 'active' ? `${apiService?.protocol}://${customDomainData.customDomain.hostname}/functions/v1/${selectedFunction?.slug}` : `${apiService?.protocol}://${endpoint}/functions/v1/${selectedFunction?.slug}` const { managementCommands, secretCommands, invokeCommands } = generateCLICommands( selectedFunction, functionUrl, anonKey ) const onUpdateFunction = async (values: any, { resetForm }: any) => { if (!projectRef) return console.error('Project ref is required') if (selectedFunction === undefined) return console.error('No edge function selected') updateEdgeFunction( { projectRef, slug: selectedFunction.slug, payload: values, }, { onSuccess: () => { resetForm({ values, initialValues: values }) toast.success(`Successfully updated edge function`) }, } ) } const onConfirmDelete = async () => { if (!projectRef) return console.error('Project ref is required') if (selectedFunction === undefined) return console.error('No edge function selected') deleteEdgeFunction({ projectRef, slug: selectedFunction.slug }) } const hasImportMap = useMemo( () => selectedFunction?.import_map || selectedFunction?.import_map_path, [selectedFunction] ) return ( <>
Import maps are{' '} {hasImportMap ? 'used' : 'not used'} {' '} for this function
Import maps allow the use of bare specifiers in functions instead of explicit import URLs