Files
supabase/apps/studio/data/storage/s3-vectors-wrapper-create-mutation.ts
Joshen LimandAli Waseem 1d203f6c93 feat: Support CLI for Vector buckets (#46381)
## Context

> [!IMPORTANT]  
> Will open up for review once CLI PR is merged and deployed so that
it's easier to test

Related PR: https://github.com/supabase/cli/pull/5230

Adding support for vector buckets for local CLI - will need to be tested
locally via `pnpm run dev:studio-local`

## To test
There's a bit of testing instructions in the linear ticket
[here](https://linear.app/supabase/issue/FE-3474/show-vector-buckets-in-local-admin-studio)
as it involves using a branch of CLI - otherwise do reach out to
Fabrizio if any help might be needed, but generally:

### Local CLI
You might need to manually set `isCli` to `true` in `StorageMenuV2` if
the "Vectors" nav item isn't showing up on the storage UI given we're
testing via `pnpm run dev:studio-local`
- [x] Can create bucket
- [x] Can delete bucket
- [x] Can create indexes
- [x] Can insert data into indexes (via FDW)
- [x] Can delete indexes

Known issues (that aren't directly solvable from FE end)
Reach out to Fabrizio for context as we were both investigating this
- PG database needs to be on 17.6 (otherwise there's no S3 vectors FDW)
- Storage version needs to be on 1.59.0

### Self-hosted (This might be tricky to actually test, but just ensure
that the code satisfies this)
- [x] Cannot see vector buckets

### Hosted
- [x] Everything works status quo

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

* **New Features**
* Vector bucket management UI and platform APIs (create/list/delete
buckets & indexes)
* Local S3 credentials endpoint and client-side hook for self‑hosted/CLI
use

* **Bug Fixes**
* Improved S3 vector setup notifications and clearer error guidance for
manual installation

* **Refactor**
* Deployment-mode gating: platform vs CLI/self‑hosted now controls
feature visibility and page behavior

* **Tests**
* Added suites covering deployment-mode gates and vector bucket
error/usage scenarios

* **Chores**
  * Build env updated to expose local S3 credential vars

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46381?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Ali Waseem <waseema393@gmail.com>
2026-06-01 08:02:22 -06:00

107 lines
3.8 KiB
TypeScript

import { PermissionAction } from '@supabase/shared-types/out/constants'
import { IS_PLATFORM } from 'common'
import { useLocalS3KeysQuery } from '../misc/local-s3-keys-query'
import { useS3AccessKeyCreateMutation } from './s3-access-key-create-mutation'
import { WRAPPERS } from '@/components/interfaces/Integrations/Wrappers/Wrappers.constants'
import { getVectorURI } from '@/components/interfaces/Storage/StorageSettings/StorageSettings.utils'
import {
getVectorBucketFDWName,
getVectorBucketFDWServerName,
getVectorBucketS3KeyName,
} from '@/components/interfaces/Storage/VectorBuckets/VectorBuckets.utils'
import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query'
import { FDWCreateVariables, useFDWCreateMutation } from '@/data/fdw/fdw-create-mutation'
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
import { useDeploymentMode } from '@/hooks/misc/useDeploymentMode'
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
export const useS3VectorsWrapperCreateMutation = () => {
const { data: project } = useSelectedProjectQuery()
const { data: localKeys } = useLocalS3KeysQuery()
const { isPlatform } = useDeploymentMode()
const { data: settings } = useProjectSettingsV2Query({ projectRef: project?.ref })
const protocol = settings?.app_config?.protocol ?? 'https'
/**
* [Joshen] Endpoint for vectors FDW needs to use docker domain
* Not sure if this affects other areas of the dashboard hence why conditionally rendering here
* instead of updating `lib/api/self-hosted/settings -> api_config`
*/
const port =
!isPlatform && !!settings
? new URL(`${protocol}://${settings.app_config?.endpoint}`).port
: null
const endpoint = !isPlatform
? `host.docker.internal:${port}`
: settings?.app_config?.storage_endpoint || settings?.app_config?.endpoint
const wrapperMeta = WRAPPERS.find((wrapper) => wrapper.name === 's3_vectors_wrapper')
const { can: canCreateCredentials } = useAsyncCheckPermissions(
PermissionAction.STORAGE_ADMIN_WRITE,
'*'
)
const { mutateAsync: createS3AccessKey, isPending: isCreatingS3AccessKey } =
useS3AccessKeyCreateMutation()
// [Joshen] Silence the error, handled upstream
const { mutateAsync: createFDW, isPending: isCreatingFDW } = useFDWCreateMutation({
onError: () => {},
})
const mutateAsync = async ({ bucketName }: { bucketName: string }) => {
let accessKey: string | undefined
let secretKey: string | undefined
if (IS_PLATFORM) {
const createS3KeyData = await createS3AccessKey({
projectRef: project?.ref,
description: getVectorBucketS3KeyName(bucketName),
})
accessKey = createS3KeyData.access_key
secretKey = createS3KeyData.secret_key
} else {
accessKey = localKeys?.accessKey
secretKey = localKeys?.secretKey
}
if (!accessKey || !secretKey) {
throw new Error(
IS_PLATFORM ? 'Failed to obtain S3 keys from the API' : 'Local S3 keys are not configured'
)
}
const wrapperName = getVectorBucketFDWName(bucketName)
const serverName = getVectorBucketFDWServerName(bucketName)
const params: FDWCreateVariables = {
projectRef: project?.ref,
connectionString: project?.connectionString,
wrapperMeta: wrapperMeta!,
formState: {
wrapper_name: wrapperName,
server_name: serverName,
vault_access_key_id: accessKey,
vault_secret_access_key: secretKey,
aws_region: settings!.region,
endpoint_url: getVectorURI(project?.ref ?? '', protocol, endpoint),
},
mode: 'skip',
tables: [],
sourceSchema: '',
targetSchema: '',
}
await createFDW(params)
}
return {
mutateAsync,
isPending: isCreatingFDW || isCreatingS3AccessKey,
hasPermission: canCreateCredentials,
}
}