mirror of
https://github.com/supabase/supabase.git
synced 2026-10-07 02:15:05 +03:00
## What The surface that shows you how to deploy a worker from the CLI, plus the product rename and the alpha framing. - **Compute → Workers.** `PRODUCT_NAME` and `CLI_NAME` now say `Workers` / `workers`, so the sidebar, page title, command menu, and every generated snippet match the CLI. One name, not two. - **`DeployWorkerDialog`** — scaffold / configure / push, with copyable `supabase workers` and `config.toml` snippets - **`WorkersEmptyState`** — an `EmptyStatePresentational` with a permission-gated deploy action - **`AlphaNotice`** on the list page, and a **New** badge on the sidebar entry (`Route.isNew`) - **`WorkerSnippetTabs`** — CLI, `config.toml`, and curl/JS/Python calls built from one worker shape. Reused by #49195. Snippet URLs resolve from the project's `app_config.endpoint` (`https://<project>/workers/v1/<name>`, the same shape as `/functions/v1/`), and fall back to `[YOUR WORKER URL]` before settings load rather than printing a wrong host. ## How to test Only on the **Mockamaster** project in staging — it is the one project in the alpha allow-list. 1. Staging dashboard → Mockamaster → **Workers** (the sidebar entry carries a **New** badge) 2. **Deploy a worker** → step through the tabs; every snippet should name the real worker URL, not a placeholder 3. Copy the cURL snippet and run it: expect `401`. Reaching a deployed worker needs a second allow-list (`WORKERS_ALLOWED_PROJECTS` in api-gateway `customer-router/wrangler.toml`), separate from the flag that unlocks the dashboard. 4. Open a project with no workers to see the empty state ## Tests `workerSnippets.test.ts` covers the generated output users copy: worker URL in all three call snippets, the `[YOUR WORKER URL]` fallback, anon vs service-role placeholder, empty-name fallback and trimming, runtime default, and every `config.toml` field. ## Unverified copy The dialog steps and the `supabase workers <sub>` subcommands come from the original POC spec, not from the shipped CLI. Same for "Dockerfile, Node.js and Deno supported" in the empty state — only Deno is confirmed end to end. Worth a check by someone who knows the CLI surface. Closes FE-4191 --------- Co-authored-by: Francesco Sansalvadore <f.sansalvadore@gmail.com>
82 lines
2.9 KiB
TypeScript
82 lines
2.9 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import { WORKERS_REGION } from './Workers.constants'
|
|
import { buildWorkerCliCommands, buildWorkerSnippets, EXAMPLE_WORKER } from './workerSnippets'
|
|
|
|
const input = (overrides: Partial<Parameters<typeof buildWorkerSnippets>[0]> = {}) => ({
|
|
...EXAMPLE_WORKER,
|
|
endpoint: 'abcdefgh.supabase.co',
|
|
...overrides,
|
|
})
|
|
|
|
describe('buildWorkerSnippets', () => {
|
|
it('points every call snippet at the worker URL', () => {
|
|
const { curl, javascript, python } = buildWorkerSnippets(input({ name: 'embed' }))
|
|
const url = 'https://abcdefgh.supabase.co/workers/v1/embed'
|
|
|
|
expect(curl).toContain(`'${url}'`)
|
|
expect(javascript).toContain(`'${url}'`)
|
|
expect(python).toContain(`"${url}"`)
|
|
})
|
|
|
|
it('leaves a placeholder URL until the project settings resolve', () => {
|
|
const { curl } = buildWorkerSnippets(input({ endpoint: undefined }))
|
|
expect(curl).toContain('[YOUR WORKER URL]')
|
|
})
|
|
|
|
it('asks for the anon key on a public worker and the service role key on a private one', () => {
|
|
expect(buildWorkerSnippets(input({ access: 'public' })).curl).toContain('[YOUR ANON KEY]')
|
|
expect(buildWorkerSnippets(input({ access: 'private' })).curl).toContain(
|
|
'[YOUR SERVICE ROLE KEY]'
|
|
)
|
|
expect(buildWorkerSnippets(input({ access: 'private' })).javascript).toContain(
|
|
'[YOUR SERVICE ROLE KEY]'
|
|
)
|
|
})
|
|
|
|
it('falls back to a placeholder name when the worker has none', () => {
|
|
expect(buildWorkerSnippets(input({ name: ' ' })).cli).toContain('my-worker')
|
|
})
|
|
|
|
it('trims the name before interpolating it', () => {
|
|
expect(buildWorkerSnippets(input({ name: ' embed ' })).cli).toContain('new embed --runtime')
|
|
})
|
|
|
|
it('defaults the runtime when the API omits it', () => {
|
|
expect(buildWorkerSnippets(input({ runtime: undefined })).cli).toContain('--runtime node')
|
|
})
|
|
|
|
it('writes the worker spec into the config.toml block', () => {
|
|
const { configToml } = buildWorkerSnippets(
|
|
input({
|
|
name: 'embed',
|
|
runtime: 'python',
|
|
size: '4gb-2vcpu',
|
|
access: 'private',
|
|
instances: 3,
|
|
})
|
|
)
|
|
|
|
expect(configToml).toContain('[workers.embed]')
|
|
expect(configToml).toContain('runtime = "python"')
|
|
expect(configToml).toContain('size = "4gb-2vcpu" # 4 GB · 2 vCPU')
|
|
expect(configToml).toContain('access = "private"')
|
|
expect(configToml).toContain('instances = 3')
|
|
expect(configToml).toContain(WORKERS_REGION)
|
|
})
|
|
})
|
|
|
|
describe('buildWorkerCliCommands', () => {
|
|
it('names the worker in every command', () => {
|
|
const commands = buildWorkerCliCommands('embed')
|
|
expect(commands).not.toHaveLength(0)
|
|
for (const { command } of commands) {
|
|
expect(command).toContain('embed')
|
|
}
|
|
})
|
|
|
|
it('falls back to a placeholder name when the worker has none', () => {
|
|
expect(buildWorkerCliCommands(' ')[0].command).toContain('my-worker')
|
|
})
|
|
})
|