Files
supabase/apps/studio/components/interfaces/Workers/workerSnippets.ts
Jordi Enric 55706ca61b fix(workers): support private deployments FE-4328 (#49902)
## Problem

The dashboard's Workers snippets said that the CLI could only deploy
public Workers and generated the obsolete access configuration field.

## Fix

Use the CLI and backend exposure field in generated config, CLI, and AI
snippets so private Worker deployments are supported.

## How to test

- Run: pnpm --filter studio test
components/interfaces/Workers/workerSnippets.test.ts
- Expected result: all 11 tests pass, including private Worker snippets
using --exposure private.

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

- **Improvements**
- Worker deployment snippets now pass the selected exposure setting
directly to the CLI.
  - Generated `config.toml` files now use the `exposure` setting.
- AI deployment guidance now documents the exposure flag, helping
clarify deployment configuration.

- **Changes**
- Removed the previous private-worker warning and public-only deployment
note from deployment guidance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-02 16:30:07 +02:00

123 lines
3.8 KiB
TypeScript

import { RUNTIMES, WORKERS_REGION, workerUrl } from './Workers.constants'
import type { WorkerAccess } from './Workers.types'
import { formatSize } from './Workers.utils'
import { CLI_NAME } from '@/lib/constants/workers'
export interface WorkerSnippetInput {
name: string
endpoint: string | undefined
protocol?: string
runtime: string | undefined
size: string
access: WorkerAccess
instances: number
}
export interface WorkerSnippets {
aiPrompt: string
configToml: string
cli: string
curl: string
javascript: string
python: string
}
export const EXAMPLE_WORKER: Omit<WorkerSnippetInput, 'endpoint' | 'protocol'> = {
name: 'my-worker',
runtime: 'node',
size: '2gb-1vcpu',
access: 'public',
instances: 1,
}
const safeName = (name: string) => (name.trim().length > 0 ? name.trim() : 'my-worker')
export function buildWorkerSnippets(input: WorkerSnippetInput): WorkerSnippets {
const name = safeName(input.name)
const runtime = input.runtime ?? 'node'
const url =
workerUrl({ endpoint: input.endpoint, protocol: input.protocol, name }) ?? '[YOUR WORKER URL]'
const cli = [
`supabase ${CLI_NAME} new ${name} --runtime ${runtime}`,
`supabase ${CLI_NAME} push ${name} --instances ${input.instances} --exposure ${input.access}`,
].join('\n')
const curl = [
`curl --request POST '${url}' \\`,
` --header 'Content-Type: application/json' \\`,
` --data '{"name":"world"}'`,
].join('\n')
const configBlock = [
`[${CLI_NAME}.${name}]`,
`runtime = "${runtime}"`,
`size = "${input.size}" # ${formatSize(input.size)}`,
`exposure = "${input.access}"`,
`instances = ${input.instances}`,
`# region is locked to ${WORKERS_REGION} at alpha`,
].join('\n')
const configToml = [`# supabase/config.toml`, ``, configBlock].join('\n')
const runtimeMeta = RUNTIMES[runtime] ?? RUNTIMES.node
// The entrypoint metadata is "<run command> <filename>" — the filename is the last token.
const entrypointFile = runtimeMeta.entrypoint.split(' ').pop()
const aiPrompt = [
`Scaffold and deploy a Supabase Workers worker named "${name}" using the ${runtimeMeta.label} runtime:`,
``,
`1. Create a supabase/${CLI_NAME}/${name}/ directory with a ${runtimeMeta.label} entrypoint (${entrypointFile}) that responds with "Hello, world!".`,
``,
`2. Add this block to supabase/config.toml:`,
'```toml',
configBlock,
'```',
``,
`3. Run \`supabase ${CLI_NAME} push ${name} --exposure ${input.access}\` to deploy it.`,
].join('\n')
const keyPlaceholder = input.access === 'public' ? '[YOUR ANON KEY]' : '[YOUR SERVICE ROLE KEY]'
const javascript = [
`const res = await fetch('${url}', {`,
` method: 'POST',`,
` headers: {`,
` Authorization: 'Bearer ${keyPlaceholder}',`,
` 'Content-Type': 'application/json',`,
` },`,
` body: JSON.stringify({ name: 'world' }),`,
`})`,
`const data = await res.json()`,
].join('\n')
const python = [
`import requests`,
``,
`res = requests.post(`,
` "${url}",`,
` headers={"Authorization": "Bearer ${keyPlaceholder}"},`,
` json={"name": "world"},`,
`)`,
`print(res.json())`,
].join('\n')
return { aiPrompt, configToml, cli, curl, javascript, python }
}
export interface WorkerCliCommand {
comment: string
command: string
}
export function buildWorkerCliCommands(name: string): WorkerCliCommand[] {
const slug = safeName(name)
return [
{ comment: 'Recreate the source locally', command: `supabase ${CLI_NAME} pull ${slug}` },
{ comment: 'Deploy a new version', command: `supabase ${CLI_NAME} push ${slug}` },
{ comment: 'Stream logs', command: `supabase ${CLI_NAME} logs ${slug} --follow` },
{ comment: 'Delete the worker', command: `supabase ${CLI_NAME} delete ${slug}` },
]
}