mirror of
https://github.com/supabase/supabase.git
synced 2026-07-03 19:54:38 +08:00
* Replace all usage of useProjectContext with useSelectedProjectQuery * Replace all usage of useSelectedProject with useSelectedProjectQuery * Replace all usage of useProjectByRef with useProjectByRefQuery * Replace all usage of useSelectedOrganization with useSelectedOrganizationQuery * Deprecate useSelectedProject, useSelectedOrganization, and useProjectByRef hooks * Deprecate ProjecContext
113 lines
3.3 KiB
TypeScript
113 lines
3.3 KiB
TypeScript
import { uniq } from 'lodash'
|
|
import { useMemo } from 'react'
|
|
|
|
import { WRAPPER_HANDLERS } from 'components/interfaces/Integrations/Wrappers/Wrappers.constants'
|
|
import {
|
|
convertKVStringArrayToJson,
|
|
wrapperMetaComparator,
|
|
} from 'components/interfaces/Integrations/Wrappers/Wrappers.utils'
|
|
import { QUEUES_SCHEMA } from 'data/database-queues/database-queues-toggle-postgrest-mutation'
|
|
import { useFDWsQuery } from 'data/fdw/fdws-query'
|
|
import { useSelectedProjectQuery } from './misc/useSelectedProject'
|
|
|
|
/**
|
|
* A list of system schemas that users should not interact with
|
|
*/
|
|
export const INTERNAL_SCHEMAS = [
|
|
'auth',
|
|
'cron',
|
|
'extensions',
|
|
'information_schema',
|
|
'net',
|
|
'pgsodium',
|
|
'pgsodium_masks',
|
|
'pgbouncer',
|
|
'pgtle',
|
|
'realtime',
|
|
'storage',
|
|
'supabase_functions',
|
|
'supabase_migrations',
|
|
'vault',
|
|
'graphql',
|
|
'graphql_public',
|
|
QUEUES_SCHEMA,
|
|
]
|
|
|
|
/**
|
|
* Get the list of schemas used by IcebergFDWs
|
|
*/
|
|
const useIcebergFdwSchemasQuery = () => {
|
|
const { data: project } = useSelectedProjectQuery()
|
|
const result = useFDWsQuery({
|
|
projectRef: project?.ref,
|
|
connectionString: project?.connectionString,
|
|
})
|
|
|
|
const schemas = useMemo(() => {
|
|
const icebergFDWs = result.data?.filter((wrapper) =>
|
|
wrapperMetaComparator(
|
|
{ handlerName: WRAPPER_HANDLERS.ICEBERG, server: { options: [] } },
|
|
wrapper
|
|
)
|
|
)
|
|
|
|
const fdwSchemas = icebergFDWs
|
|
?.map((fdw) => convertKVStringArrayToJson(fdw.server_options))
|
|
.map((options) => options['supabase_target_schema'])
|
|
.flatMap((s) => s?.split(','))
|
|
.filter(Boolean)
|
|
|
|
return uniq(fdwSchemas)
|
|
}, [result.data])
|
|
|
|
return { ...result, data: schemas }
|
|
}
|
|
|
|
/**
|
|
* Returns a list of schemas that are protected by Supabase (internal schemas or schemas used by Iceberg FDWs).
|
|
*/
|
|
export const useProtectedSchemas = ({
|
|
excludeSchemas = [],
|
|
}: { excludeSchemas?: string[] } = {}) => {
|
|
// Stabilize the excludeSchemas array to prevent unnecessary re-computations
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
const stableExcludeSchemas = useMemo(() => excludeSchemas, [JSON.stringify(excludeSchemas)])
|
|
|
|
const result = useIcebergFdwSchemasQuery()
|
|
|
|
const schemas = useMemo<{ name: string; type: 'fdw' | 'internal' }[]>(() => {
|
|
const internalSchemas = INTERNAL_SCHEMAS.map((s) => ({ name: s, type: 'internal' as const }))
|
|
const icebergFdwSchemas = result.data?.map((s) => ({ name: s, type: 'fdw' as const }))
|
|
|
|
const schemas = uniq([...internalSchemas, ...icebergFdwSchemas])
|
|
return schemas.filter((schema) => !stableExcludeSchemas.includes(schema.name))
|
|
}, [result.data, stableExcludeSchemas])
|
|
|
|
return { ...result, data: schemas }
|
|
}
|
|
|
|
/**
|
|
* Returns whether a given schema is protected by Supabase (internal schema or schema used by Iceberg FDWs).
|
|
*/
|
|
export const useIsProtectedSchema = ({
|
|
schema,
|
|
excludedSchemas = [],
|
|
}: {
|
|
schema: string
|
|
excludedSchemas?: string[]
|
|
}):
|
|
| { isSchemaLocked: false; reason: undefined }
|
|
| { isSchemaLocked: true; reason: 'fdw' | 'internal' } => {
|
|
const { data: schemas } = useProtectedSchemas({ excludeSchemas: excludedSchemas })
|
|
|
|
const foundSchema = schemas.find((s) => s.name === schema)
|
|
|
|
if (foundSchema) {
|
|
return {
|
|
isSchemaLocked: true,
|
|
reason: foundSchema.type,
|
|
}
|
|
}
|
|
return { isSchemaLocked: false, reason: undefined }
|
|
}
|