ronantakizawa/codereview-bench huggingface dataset:
Repository: supabase/supabase
File: apps/studio/data/storage/iceberg-namespace-create-mutation.ts (TypeScript)

Code before:
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'

import { useTemporaryAPIKeyQuery } from 'data/api-keys/temp-api-keys-query'
import { constructHeaders, fetchHandler, handleError } from 'data/fetchers'
import type { ResponseError, UseCustomMutationOptions } from 'types'
import { storageKeys } from './keys'

type CreateIcebergNamespaceVariables = {
  catalogUri: string
  warehouse: string
  namespace: string
}

async function createIcebergNamespace({
  catalogUri,
  warehouse,
  namespace,
  tempApiKey,
}: CreateIcebergNamespaceVariables & { tempApiKey?: string }) {
  let headers = new Headers()
  headers = await constructHeaders({
    'Content-Type': 'application/json',
    apikey: `${tempApiKey}`,
  })
  headers.delete('Authorization')

  const url = `${catalogUri}/v1/${warehouse}/namespaces`.replaceAll(/(?<!:)\/\//g, '/')

  try {
    const response = await fetchHandler(url, {
      headers,
      method: 'POST',
      body: JSON.stringify({
        namespace: namespace,
      }),
    })

    const result = await response.json()
    if (result.error) {
      if (result.error.message) {
        throw new Error(result.error.message)
      }
      throw new Error('Failed to create Iceberg namespace')
    }
    return result
  } catch (error) {
    handleError(error)
  }

Review comment (suggestion):
```suggestion
    apikey: tempApiKey,
```

Should we not just throw if `tempApiKey` is undefined? Otherwise we're going to send `apikey: undefined` which I assume will error on the backend anyway 😄 

Code after:
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'

import { useTemporaryAPIKeyQuery } from 'data/api-keys/temp-api-keys-query'
import { constructHeaders, fetchHandler, handleError } from 'data/fetchers'
import type { ResponseError, UseCustomMutationOptions } from 'types'
import { storageKeys } from './keys'

type CreateIcebergNamespaceVariables = {
  catalogUri: string
  warehouse: string
  namespace: string
}

const errorPrefix = 'Failed to create Iceberg namespace'

async function createIcebergNamespace({
  catalogUri,
  warehouse,
  namespace,
  tempApiKey,
}: CreateIcebergNamespaceVariables & { tempApiKey?: string }) {
  try {
    if (!tempApiKey) throw new Error(`${errorPrefix}: API Key missing`)

    let headers = new Headers()
    headers = await constructHeaders({
      'Content-Type': 'application/json',
      apikey: tempApiKey,
    })
    headers.delete('Authorization')

    const url = `${catalogUri}/v1/${warehouse}/namespaces`.replaceAll(/(?<!:)\/\//g, '/')

    const response = await fetchHandler(url, {
      headers,
      method: 'POST',
      body: JSON.stringify({ namespace: namespace }),
    })
    const result = await response.json()
    if (result.error) {
      if (result.error.message) throw new Error(`${errorPrefix}: ${result.error.message}`)
      else throw new Error(errorPrefix)
    }

    return result
  } catch (error) {
    handleError(error)
  }
Repository: supabase/supabase
File: apps/studio/data/storage/iceberg-namespace-table-delete-mutation.ts (TypeScript)

Code before:
import { toast } from 'sonner'

import { useTemporaryAPIKeyQuery } from 'data/api-keys/temp-api-keys-query'
import { constructHeaders, fetchHandler, handleError } from 'data/fetchers'
import type { ResponseError, UseCustomMutationOptions } from 'types'
import { storageKeys } from './keys'

type DeleteIcebergNamespaceTableVariables = {
  catalogUri: string
  warehouse: string
  namespace: string
  table: string
  projectRef?: string
}

async function deleteIcebergNamespaceTable({
  catalogUri,
  warehouse,
  namespace,
  table,
  tempApiKey,
}: DeleteIcebergNamespaceTableVariables & { tempApiKey?: string }) {
  let headers = new Headers()
  headers = await constructHeaders({
    'Content-Type': 'application/json',
    apikey: `${tempApiKey}`,
  })
  headers.delete('Authorization')

  const url =
    `${catalogUri}/v1/${warehouse}/namespaces/${namespace}/tables/${table}?purgeRequested=true`.replaceAll(
      /(?<!:)\/\//g,
      '/'
    )

  try {
    if (!tempApiKey) {
      throw new Error('')
    }
    const response = await fetchHandler(url, {
      headers,
      method: 'DELETE',
    })
    return response.status === 204
  } catch (error) {
    handleError(error)
  }
}

type IcebergNamespaceTableDeleteData = Awaited<ReturnType<typeof deleteIcebergNamespaceTable>>


Review comment (suggestion):
```suggestion
    apikey: tempApiKey,
```

same here

Code after:
import { toast } from 'sonner'

import { useTemporaryAPIKeyQuery } from 'data/api-keys/temp-api-keys-query'
import { constructHeaders, fetchHandler, handleError } from 'data/fetchers'
import type { ResponseError, UseCustomMutationOptions } from 'types'
import { storageKeys } from './keys'

type DeleteIcebergNamespaceTableVariables = {
  catalogUri: string
  warehouse: string
  namespace: string
  table: string
  projectRef?: string
}

const errorPrefix = 'Failed to delete Iceberg namespace table'

async function deleteIcebergNamespaceTable({
  catalogUri,
  warehouse,
  namespace,
  table,
  tempApiKey,
}: DeleteIcebergNamespaceTableVariables & { tempApiKey?: string }) {
  try {
    if (!tempApiKey) throw new Error(`${errorPrefix}: API Key missing`)

    let headers = new Headers()
    headers = await constructHeaders({
      'Content-Type': 'application/json',
      apikey: tempApiKey,
    })
    headers.delete('Authorization')

    const url =
      `${catalogUri}/v1/${warehouse}/namespaces/${namespace}/tables/${table}?purgeRequested=true`.replaceAll(
        /(?<!:)\/\//g,
        '/'
      )

    const response = await fetchHandler(url, { headers, method: 'DELETE' })
    const result = await response.json()
    if (result.error) {
      if (result.error.message) throw new Error(`${errorPrefix}: ${result.error.message}`)
      else throw new Error(errorPrefix)
    }

    return response.status === 204
  } catch (error) {
    handleError(error)
  }
Repository: supabase/supabase
File: apps/studio/data/storage/iceberg-namespace-tables-query.ts (TypeScript)

Code before:
import { useQuery } from '@tanstack/react-query'

import { useTemporaryAPIKeyQuery } from 'data/api-keys/temp-api-keys-query'
import { constructHeaders, fetchHandler, handleError } from 'data/fetchers'
import type { ResponseError, UseCustomQueryOptions } from 'types'
import { storageKeys } from './keys'

type GetNamespaceTablesVariables = {
  catalogUri: string
  warehouse: string
  namespace: string
  projectRef?: string
}

async function getNamespaceTables({
  catalogUri,
  warehouse,
  namespace,
  tempApiKey,
}: GetNamespaceTablesVariables & { tempApiKey?: string }) {
  let headers = new Headers()
  headers = await constructHeaders({
    'Content-Type': 'application/json',
    apikey: tempApiKey ?? '',
  })
  headers.delete('Authorization')

  const url = `${catalogUri}/v1/${warehouse}/namespaces/${namespace}/tables`.replaceAll(
    /(?<!:)\/\//g,
    '/'
  )

  try {
    const response = await fetchHandler(url, {
      headers,
      method: 'GET',
    })

    const result = await response.json()
    if (result.error) {
      if (result.error.message) {
        throw new Error(result.error.message)
      }
      throw new Error('Failed to get iceberg namespace')
    }
    const r = result as { identifiers: { name: string; namespace: string[] }[] }
    return r.identifiers.map((i) => i.name)
  } catch (error) {
    handleError(error)

Review comment (suggestion):
```suggestion
    apikey: tempApiKey,
```

same here

Code after:
import { useQuery } from '@tanstack/react-query'

import { useTemporaryAPIKeyQuery } from 'data/api-keys/temp-api-keys-query'
import { constructHeaders, fetchHandler, handleError } from 'data/fetchers'
import type { ResponseError, UseCustomQueryOptions } from 'types'
import { storageKeys } from './keys'

type GetNamespaceTablesVariables = {
  catalogUri: string
  warehouse: string
  namespace: string
  projectRef?: string
}

const errorPrefix = 'Failed to retrieve Iceberg namespace tables'

async function getNamespaceTables({
  catalogUri,
  warehouse,
  namespace,
  tempApiKey,
}: GetNamespaceTablesVariables & { tempApiKey?: string }) {
  try {
    if (!tempApiKey) throw new Error(`${errorPrefix}: API Key missing`)

    let headers = new Headers()
    headers = await constructHeaders({
      'Content-Type': 'application/json',
      apikey: tempApiKey,
    })
    headers.delete('Authorization')

    const url = `${catalogUri}/v1/${warehouse}/namespaces/${namespace}/tables`.replaceAll(
      /(?<!:)\/\//g,
      '/'
    )

    const response = await fetchHandler(url, { headers, method: 'GET' })
    const result = await response.json()
    if (result.error) {
      if (result.error.message) throw new Error(`${errorPrefix}: ${result.error.message}`)
      else throw new Error(errorPrefix)
    }

    const r = result as { identifiers: { name: string; namespace: string[] }[] }
    return r.identifiers.map((i) => i.name)
  } catch (error) {
    handleError(error)
  }
Repository: supabase/supabase
File: apps/studio/data/storage/iceberg-namespaces-query.ts (TypeScript)

Code before:
import { useQuery } from '@tanstack/react-query'

import { useTemporaryAPIKeyQuery } from 'data/api-keys/temp-api-keys-query'
import { constructHeaders, fetchHandler, handleError } from 'data/fetchers'
import type { ResponseError, UseCustomQueryOptions } from 'types'
import { storageKeys } from './keys'

type GetNamespacesVariables = {
  catalogUri: string
  warehouse: string
  projectRef?: string
}

// [Joshen] Investigate if we can use the temp API keys here
async function getNamespaces({
  catalogUri,
  warehouse,
  tempApiKey,
}: GetNamespacesVariables & { tempApiKey?: string }) {
  console.log('getNamespaces', { catalogUri, warehouse, tempApiKey })

  let headers = new Headers()
  headers = await constructHeaders({
    'Content-Type': 'application/json',
    apikey: tempApiKey ?? '',
  })
  headers.delete('Authorization')

  const url = `${catalogUri}/v1/${warehouse}/namespaces`.replaceAll(/(?<!:)\/\//g, '/')

  try {
    const response = await fetchHandler(url, {
      headers,
      method: 'GET',
    })

    const result = await response.json()
    if (result.error) {
      if (result.error.message) {
        throw new Error(result.error.message)
      }
      throw new Error('Failed to get iceberg namespaces')
    }
    const r = result as { namespaces: string[][] }
    return r.namespaces.flat()
  } catch (error) {
    handleError(error)
  }
}


Review comment (suggestion):
```suggestion
    apikey: tempApiKey,
```

same here

Code after:
import { useQuery } from '@tanstack/react-query'

import { useTemporaryAPIKeyQuery } from 'data/api-keys/temp-api-keys-query'
import { constructHeaders, fetchHandler, handleError } from 'data/fetchers'
import type { ResponseError, UseCustomQueryOptions } from 'types'
import { storageKeys } from './keys'

type GetNamespacesVariables = {
  catalogUri: string
  warehouse: string
  projectRef?: string
}

const errorPrefix = 'Failed to delete Iceberg namespaces'

async function getNamespaces({
  catalogUri,
  warehouse,
  tempApiKey,
}: GetNamespacesVariables & { tempApiKey?: string }) {
  try {
    if (!tempApiKey) throw new Error(`${errorPrefix}: API Key missing`)

    let headers = new Headers()
    headers = await constructHeaders({
      'Content-Type': 'application/json',
      apikey: tempApiKey,
    })
    headers.delete('Authorization')

    const url = `${catalogUri}/v1/${warehouse}/namespaces`.replaceAll(/(?<!:)\/\//g, '/')

    const response = await fetchHandler(url, { headers, method: 'GET' })
    const result = await response.json()
    if (result.error) {
      if (result.error.message) throw new Error(`${errorPrefix}: ${result.error.message}`)
      else throw new Error(errorPrefix)
    }

    const r = result as { namespaces: string[][] }
    return r.namespaces.flat()
  } catch (error) {
    handleError(error)
  }
}

type IcebergNamespacesData = Awaited<ReturnType<typeof getNamespaces>>

export type IcebergNamespacesError = ResponseError
Repository: supabase/supabase
File: apps/studio/data/storage/keys.ts (TypeScript)

Code before:
    [projectRef, 'catalog', catalog, 'warehouse', warehouse, 'namespaces', apikey].filter(Boolean),
  icebergNamespace: (catalog: string, warehouse: string, namespace: string) =>
    ['catalog', catalog, 'warehouse', warehouse, 'namespaces', namespace] as const,
  icebergNamespaceTables: ({
    projectRef,
    catalog,
    warehouse,
    namespace,
    apikey,
  }: {
    projectRef?: string
    catalog: string
    warehouse: string
    namespace: string
    apikey?: string
  }) =>
    [
      projectRef,
      'catalog',
      catalog,
      'warehouse',
      warehouse,
      'namespaces',
      namespace,
      'tables',
      apikey,
    ].filter(Boolean),
}


Review comment (suggestion):
```suggestion
  }: {
    projectRef?: string
    catalog: string
    warehouse: string
    namespace: string
  }) =>
    [
      projectRef,
      'catalog',
      catalog,
      'warehouse',
      warehouse,
      'namespaces',
      namespace,
      'tables',
```

Code after:
export const storageKeys = {
  buckets: (projectRef: string | undefined) => ['projects', projectRef, 'buckets'] as const,
  analyticsBuckets: (projectRef: string | undefined) =>
    ['projects', projectRef, 'analytics-buckets'] as const,
  vectorBuckets: (projectRef: string | undefined) =>
    ['projects', projectRef, 'vector-buckets'] as const,
  vectorBucket: (projectRef: string | undefined, vectorbucketName: string | undefined) =>
    ['projects', projectRef, 'vector-bucket', vectorbucketName] as const,
  vectorBucketsIndexes: (projectRef: string | undefined, vectorBucketName: string | undefined) =>
    ['projects', projectRef, 'vector-buckets', vectorBucketName, 'indexes'] as const,
  archive: (projectRef: string | undefined) => ['projects', projectRef, 'archive'] as const,
  icebergNamespaces: ({
    projectRef,
    catalog,
    warehouse,
  }: {
    projectRef?: string
    catalog: string
    warehouse: string
  }) => [projectRef, 'catalog', catalog, 'warehouse', warehouse, 'namespaces'] as const,
  icebergNamespace: (catalog: string, warehouse: string, namespace: string) =>
    ['catalog', catalog, 'warehouse', warehouse, 'namespaces', namespace] as const,
  icebergNamespaceTables: ({
    projectRef,
    catalog,
    warehouse,
    namespace,
  }: {
    projectRef?: string
    catalog: string
    warehouse: string
    namespace: string
  }) =>
    [
      projectRef,
      'catalog',
      catalog,
      'warehouse',
      warehouse,
      'namespaces',
      namespace,
      'tables',
    ] as const,
}
Repository: supabase/supabase
File: apps/studio/components/ui/EntityTypeIcon.tsx (TypeScript)

Code before:
  }

  if (type === 'schema') {
    return <GitBranch size={size} strokeWidth={strokeWidth} />
  }

  if (type === ENTITY_TYPE.VIEW) {
    return (
      <Eye
        size={size}
        strokeWidth={strokeWidth}
        className={cn(
          'text-foreground-muted group-hover:text-foreground-lighter',
          isActive && 'text-foreground-lighter',
          'transition-colors'
        )}
      />
    )
  }

  return (
    <div
      className={cn(
        'flex items-center justify-center text-xs h-4 w-4 rounded-[2px] font-bold',
        type === ENTITY_TYPE.FOREIGN_TABLE && 'text-yellow-900 bg-yellow-500',
        type === ENTITY_TYPE.MATERIALIZED_VIEW && 'text-purple-1000 bg-purple-500',
        type === ENTITY_TYPE.PARTITIONED_TABLE && 'text-foreground-light bg-border-stronger'
      )}
    >
      {Object.entries(ENTITY_TYPE)
        .find(([, value]) => value === type)?.[0]?.[0]
        ?.toUpperCase()}
    </div>
  )
}


Review comment (suggestion):
This fixes the text legibility on light mode. Using `text-yellow-1100` looks like an old banana. Gross.

Code after:
  }

  if (type === 'schema') {
    return <GitBranch size={size} strokeWidth={strokeWidth} />
  }

  if (type === ENTITY_TYPE.VIEW) {
    return (
      <Eye
        size={size}
        strokeWidth={strokeWidth}
        className={cn(
          'text-foreground-muted group-hover:text-foreground-lighter',
          isActive && 'text-foreground-lighter',
          'transition-colors'
        )}
      />
    )
  }

  return (
    <div
      className={cn(
        'flex items-center justify-center text-xs h-4 w-4 rounded-[2px] font-bold',
        type === ENTITY_TYPE.FOREIGN_TABLE &&
          'text-warning-600/80 dark:text-yellow-900 bg-yellow-500',
        type === ENTITY_TYPE.MATERIALIZED_VIEW && 'text-purple-1000 bg-purple-500',
        type === ENTITY_TYPE.PARTITIONED_TABLE && 'text-foreground-light bg-border-stronger'
      )}
    >
      {Object.entries(ENTITY_TYPE)
        .find(([, value]) => value === type)?.[0]?.[0]
        ?.toUpperCase()}
    </div>
  )
}
Repository: supabase/supabase
File: apps/studio/components/interfaces/Storage/AnalyticsBuckets/useSelectedAnalyticsBucket.ts (TypeScript)

Code before:
import { useParams } from 'common'
import { useIsAnalyticsBucketsEnabled } from 'data/config/project-storage-config-query'
import { useAnalyticsBucketsQuery } from 'data/storage/analytics-buckets-query'

export const useSelectedAnalyticsBucket = () => {
  const { ref, bucketId } = useParams()
  const hasIcebergEnabled = useIsAnalyticsBucketsEnabled({ projectRef: ref })

  const {
    data = [],
    error,
    isLoading,
    isSuccess,
    isError,
  } = useAnalyticsBucketsQuery({ projectRef: ref }, { enabled: hasIcebergEnabled })

  const bucket = data.find((x) => x.id === bucketId)

  return { data: bucket, isLoading, isSuccess, isError, error }
}


Review comment (suggestion):
If possible we should be returning the query result directly instead of returning a new object. That way the react-query typing magic will continue to work.

You can get the same result by using `select` in the react query options to do the `data.find((x) => x.id === bucketId)`.

Code after:
import { useParams } from 'common'
import { useIsAnalyticsBucketsEnabled } from 'data/config/project-storage-config-query'
import { useAnalyticsBucketsQuery } from 'data/storage/analytics-buckets-query'

export const useSelectedAnalyticsBucket = () => {
  const { ref, bucketId } = useParams()
  const hasIcebergEnabled = useIsAnalyticsBucketsEnabled({ projectRef: ref })

  return useAnalyticsBucketsQuery(
    { projectRef: ref },
    {
      enabled: hasIcebergEnabled,
      select(data) {
        return data.find((x) => x.id === bucketId)
      },
    }
  )
}
Repository: supabase/supabase
File: e2e/studio/playwright.config.ts (TypeScript)

Code before:
  projects: [
    {
      name: 'setup',
      testMatch: /.*\.setup\.ts/,
    },
    {
      name: 'Features',
      testDir: './features',
      testMatch: /.*\.spec\.ts/,
      dependencies: ['setup'],
      use: {
        browserName: 'chromium',
        screenshot: 'off',
        // Only use storage state if authentication is enabled. When AUTHENTICATION=false
        // we should not require a pre-generated storage state file.
        storageState: env.AUTHENTICATION ? STORAGE_STATE_PATH : undefined,
      },
    },
  ],
  reporter: [
    ['list'],
    ['html', { open: 'never' }],
    ['json', { outputFile: 'test-results/test-results.json' }],
  ],
  webServer: {
    command: 'pnpm -w run e2e:setup',
    port: WEB_SERVER_PORT,
    timeout: WEB_SERVER_TIMEOUT,
  },
})


Review comment (suggestion):
```suggestion
    command: 'pnpm --workspace-root run e2e:setup',
```

Tiny nit, I have a personal preference for long-form flags in committed code b/c it makes it easier to understand what's going on later. Feel free to ignore if you disagree :D

Code after:
  projects: [
    {
      name: 'setup',
      testMatch: /.*\.setup\.ts/,
    },
    {
      name: 'Features',
      testDir: './features',
      testMatch: /.*\.spec\.ts/,
      dependencies: ['setup'],
      use: {
        browserName: 'chromium',
        screenshot: 'off',
        // Only use storage state if authentication is enabled. When AUTHENTICATION=false
        // we should not require a pre-generated storage state file.
        storageState: env.AUTHENTICATION ? STORAGE_STATE_PATH : undefined,
      },
    },
  ],
  reporter: [
    ['list'],
    ['html', { open: 'never' }],
    ['json', { outputFile: 'test-results/test-results.json' }],
  ],
  webServer: {
    command: 'pnpm --workspace-root run e2e:setup',
    port: WEB_SERVER_PORT,
    timeout: WEB_SERVER_TIMEOUT,
  },
})
Repository: supabase/supabase
File: packages/ui-patterns/src/McpUrlBuilder/types.ts (TypeScript)

Code before:
export interface McpUrlBuilderConfig {
  projectRef: string
  readonly?: boolean
  features?: string[]
}

export interface McpClientBaseConfig {
  mcpServers: {
    supabase: {
      url: string
    }
  }
}

export interface CursorMcpConfig extends McpClientBaseConfig {}

export interface VSCodeMcpConfig {
  servers: {
    supabase: {
      type: 'http'
      url: string
    }
  }
}

export interface WindsurfMcpConfig {
  mcpServers: {
    supabase: {
      command: 'npx'
      args: ['-y', 'mcp-remote', string]
    }
  }
}

export interface ClaudeCodeMcpConfig extends McpClientBaseConfig {
  mcpServers: {
    supabase: {
      type: 'http'
      url: string
    }
  }
}

export interface ClaudeDesktopMcpConfig extends McpClientBaseConfig {
  mcpServers: {
    supabase: {
      type: 'http'
      url: string
    }
  }
}

Review comment (suggestion):
Apparently, VSCode changed their json property from `mcpServers` to `servers`
https://code.visualstudio.com/docs/copilot/customization/mcp-servers#_other-options-to-add-an-mcp-server

Code after:
    onCopy: (type?: McpOnCopyCallback) => void
  ) => React.ReactNode
  alternateInstructions?: (
    config: McpClientConfig,
    onCopy: (type?: McpOnCopyCallback) => void
  ) => React.ReactNode
}

export interface McpUrlBuilderConfig {
  projectRef: string
  readonly?: boolean
  features?: string[]
}

export interface McpClientBaseConfig {
  mcpServers: {
    supabase: {
      url: string
    }
  }
}

export interface CursorMcpConfig extends McpClientBaseConfig {}

export interface VSCodeMcpConfig {
  servers: {
    supabase: {
      type: 'http'
      url: string
    }
  }
}

export interface WindsurfMcpConfig {
  mcpServers: {
    supabase: {
      command: 'npx'
      args: ['-y', 'mcp-remote', string]
    }
  }
}

export interface ClaudeCodeMcpConfig extends McpClientBaseConfig {
  mcpServers: {
    supabase: {
      type: 'http'
      url: string
    }
  }
}