Files
supabase/apps/studio/components/interfaces/Functions/EdgeFunctionDetails/EdgeFunctionDetails.utils.tsx
Vaibhav 83e6552d71 fix: preserve function responses (#47920)
- adds up to: https://github.com/supabase/cli/pull/5862

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added an “Error docs” link in Edge Function testing UI when an
`sb-error-code` header is present.

* **Bug Fixes**
* Improved the Edge Function test proxy to consistently preserve
upstream status, headers (including repeated headers), and response
bodies without transformation.
* Enhanced handling for invalid function URLs and upstream fetch
failures.

* **Tests**
* Added unit, API, and Playwright E2E coverage for error docs linking
and response proxy behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-20 18:58:30 +01:00

120 lines
3.3 KiB
TypeScript

import { getAnchor } from '@ui/components/CustomHTMLElements/CustomHTMLElements.utils'
import { EdgeFunction } from '@/data/edge-functions/edge-function-query'
import { DOCS_URL } from '@/lib/constants'
export const generateCLICommands = ({
selectedFunction,
functionUrl,
anonKey,
}: {
selectedFunction?: EdgeFunction
functionUrl: string
anonKey: string
}) => {
const managementCommands: any = [
{
command: `supabase functions deploy ${selectedFunction?.slug}`,
description: 'This will overwrite the deployed function with your new function',
jsx: () => {
return (
<>
<span className="text-brand">supabase</span> functions deploy {selectedFunction?.slug}
</>
)
},
comment: 'Deploy a new version',
},
{
command: `supabase functions delete ${selectedFunction?.slug}`,
description: 'This will remove the function and all the logs associated with it',
jsx: () => {
return (
<>
<span className="text-brand">supabase</span> functions delete {selectedFunction?.slug}
</>
)
},
comment: 'Delete the function',
},
]
const secretCommands: any = [
{
command: `supabase secrets list`,
description: 'This will list all the secrets for your project',
jsx: () => {
return (
<>
<span className="text-brand">supabase</span> secrets list
</>
)
},
comment: 'View all secrets',
},
{
command: `supabase secrets set NAME1=VALUE1 NAME2=VALUE2`,
description: 'This will set secrets for your project',
jsx: () => {
return (
<>
<span className="text-brand">supabase</span> secrets set NAME1=VALUE1 NAME2=VALUE2
</>
)
},
comment: 'Set secrets for your project',
},
{
command: `supabase secrets unset NAME1 NAME2 `,
description: 'This will delete secrets for your project',
jsx: () => {
return (
<>
<span className="text-brand">supabase</span> secrets unset NAME1 NAME2
</>
)
},
comment: 'Unset secrets for your project',
},
]
const invokeCommands: any = [
{
command: `curl -L -X POST '${functionUrl}' -H 'Authorization: Bearer ${
anonKey ?? '[YOUR ANON KEY]'
}' --data '{"name":"Functions"}'`,
description: 'Invokes the hello function',
jsx: () => {
return (
<>
<span className="text-brand">curl</span> -L -X POST '{functionUrl}'{' '}
{selectedFunction?.verify_jwt
? `-H
'Authorization: Bearer [YOUR ANON KEY]' `
: ''}
{`--data '{"name":"Functions"}'`}
</>
)
},
comment: 'Invoke your function',
},
]
return { managementCommands, secretCommands, invokeCommands }
}
export const getEdgeFunctionErrorDocs = (headers: Record<string, string | string[]>) => {
const header = Object.entries(headers).find(
([name]) => name.toLowerCase() === 'sb-error-code'
)?.[1]
const code = (Array.isArray(header) ? header[0] : header)?.trim()
const anchor = code ? getAnchor(code) : undefined
if (!code || !anchor) return undefined
return {
code,
href: `${DOCS_URL}/guides/functions/error-codes#${anchor}`,
}
}