mirror of
https://github.com/supabase/supabase.git
synced 2026-07-03 11:14:34 +08:00
* add initial installation flow of stripe sync engine * update docs link * Add supabase_vault extension dep * Add stripe logo to sync engine integration * Move overview content to bottom of integration pages * Add sync state to stripe sync page * only check sync state if stripe integration is installed * Use proper stripe-sync package and setup flows * Improve sync engine installation ux * Remove unused hardcoded dep * Add alpha status to stripe sync engine integration * fix typo * run format * fix types * Rename the stripe-sync path to remove the 'integration". The path needs to have BASE_PATH to work on prod. * Design tidy up (#41337) UI tidy up * update to latest sync engine package * Add stripe key verification * Remove noop try/catch * Add integration isntallation telelemtry * Add basic settings page * Address coderabbit comments * remove unused dep * Remove state setting on render * s/description/comment * Cleanup settings screen UI * Improve settings screen design * update schema test snapshot * Use latest stripe-sync-engine package * Update repo url to new official location * revert marketing change * Update stripe sync engine package * Add link to table from overview page * Add feature flag and improve telemetry * Fix missing useMemo dep * add uninstall telemetry note --------- Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com> Co-authored-by: Saxon Fletcher <saxonafletcher@gmail.com>
122 lines
4.3 KiB
TypeScript
122 lines
4.3 KiB
TypeScript
import { useMemo } from 'react'
|
|
|
|
import { useDatabaseExtensionsQuery } from 'data/database-extensions/database-extensions-query'
|
|
import { useSchemasQuery } from 'data/database/schemas-query'
|
|
import { useFDWsQuery } from 'data/fdw/fdws-query'
|
|
import { useFlag } from 'common'
|
|
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
|
|
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
|
|
import { EMPTY_ARR } from 'lib/void'
|
|
import {
|
|
INSTALLATION_INSTALLED_SUFFIX,
|
|
STRIPE_SCHEMA_COMMENT_PREFIX,
|
|
} from 'stripe-experiment-sync/supabase'
|
|
import { wrapperMetaComparator } from '../Wrappers/Wrappers.utils'
|
|
import { INTEGRATIONS } from './Integrations.constants'
|
|
|
|
export const useInstalledIntegrations = () => {
|
|
const { data: project } = useSelectedProjectQuery()
|
|
const { integrationsWrappers } = useIsFeatureEnabled(['integrations:wrappers'])
|
|
const stripeSyncEnabled = useFlag('enableStripeSyncEngineIntegration')
|
|
|
|
const allIntegrations = useMemo(() => {
|
|
return INTEGRATIONS.filter((integration) => {
|
|
if (
|
|
!integrationsWrappers &&
|
|
(integration.type === 'wrapper' || integration.id.endsWith('_wrapper'))
|
|
) {
|
|
return false
|
|
}
|
|
if (!stripeSyncEnabled && integration.id === 'stripe_sync_engine') {
|
|
return false
|
|
}
|
|
return true
|
|
})
|
|
}, [integrationsWrappers, stripeSyncEnabled])
|
|
|
|
const {
|
|
data,
|
|
error: fdwError,
|
|
isError: isErrorFDWs,
|
|
isPending: isFDWLoading,
|
|
isSuccess: isSuccessFDWs,
|
|
} = useFDWsQuery({
|
|
projectRef: project?.ref,
|
|
connectionString: project?.connectionString,
|
|
})
|
|
const {
|
|
data: extensions,
|
|
error: extensionsError,
|
|
isError: isErrorExtensions,
|
|
isPending: isExtensionsLoading,
|
|
isSuccess: isSuccessExtensions,
|
|
} = useDatabaseExtensionsQuery({
|
|
projectRef: project?.ref,
|
|
connectionString: project?.connectionString,
|
|
})
|
|
|
|
const {
|
|
data: schemas,
|
|
error: schemasError,
|
|
isError: isErrorSchemas,
|
|
isPending: isSchemasLoading,
|
|
isSuccess: isSuccessSchemas,
|
|
} = useSchemasQuery({
|
|
projectRef: project?.ref,
|
|
connectionString: project?.connectionString,
|
|
})
|
|
|
|
const isHooksEnabled = schemas?.some((schema) => schema.name === 'supabase_functions')
|
|
const wrappers = useMemo(() => data ?? EMPTY_ARR, [data])
|
|
|
|
const installedIntegrations = useMemo(() => {
|
|
return allIntegrations
|
|
.filter((integration) => {
|
|
// special handling for supabase webhooks
|
|
if (integration.id === 'webhooks') {
|
|
return isHooksEnabled
|
|
}
|
|
if (integration.id === 'stripe_sync_engine') {
|
|
const stripeSchema = schemas?.find(({ name }) => name === 'stripe')
|
|
return (
|
|
!!stripeSchema?.comment?.startsWith(STRIPE_SCHEMA_COMMENT_PREFIX) &&
|
|
!!stripeSchema.comment?.includes(INSTALLATION_INSTALLED_SUFFIX)
|
|
)
|
|
}
|
|
if (integration.type === 'wrapper') {
|
|
return wrappers.find((w) => wrapperMetaComparator(integration.meta, w))
|
|
}
|
|
if (integration.type === 'postgres_extension') {
|
|
return integration.requiredExtensions.every((extName) => {
|
|
const foundExtension = (extensions ?? []).find((ext) => ext.name === extName)
|
|
return !!foundExtension?.installed_version
|
|
})
|
|
}
|
|
return false
|
|
})
|
|
.sort((a, b) => a.name.localeCompare(b.name))
|
|
}, [allIntegrations, wrappers, extensions, schemas, isHooksEnabled])
|
|
|
|
// available integrations are all integrations that can be installed. If an integration can't be installed (needed
|
|
// extensions are not available on this DB image), the UI will provide a tooltip explaining why.
|
|
const availableIntegrations = useMemo(
|
|
() => allIntegrations.sort((a, b) => a.name.localeCompare(b.name)),
|
|
[allIntegrations]
|
|
)
|
|
|
|
const error = fdwError || extensionsError || schemasError
|
|
const isLoading = isSchemasLoading || isFDWLoading || isExtensionsLoading
|
|
const isError = isErrorFDWs || isErrorExtensions || isErrorSchemas
|
|
const isSuccess = isSuccessFDWs && isSuccessExtensions && isSuccessSchemas
|
|
|
|
return {
|
|
// show all integrations at once instead of showing partial results
|
|
installedIntegrations: isLoading ? EMPTY_ARR : installedIntegrations,
|
|
availableIntegrations: isLoading ? EMPTY_ARR : availableIntegrations,
|
|
error,
|
|
isError,
|
|
isLoading,
|
|
isSuccess,
|
|
}
|
|
}
|