mirror of
https://github.com/supabase/supabase.git
synced 2026-10-12 12:55:06 +03:00
This PR: * Adds an upgrade flow to the stripe sync engine, allowing users to upgrade to the latest version when it becomes available. * When a new version of sync engine becomes available, users will see an upgrade button instead of install button. * Bumps `supabase-management-js` to version 2.0.2 and `stripe-experiment-sync` to version 1.0.27. * Uses `parseSchemaComment` and related logic from the `stripe-experiment-sync` package in order to avoid writing duplicate code in supabase ui. * Allows installation/uninstallation to timeout after 5 minutes to avoid these operations from getting stuck in case an error occurs in their processing. This allows users to retry the operation, as opposed to the older behaviour where the users always see a spinner on the install/uninstall button and couldn't do anything. * Remove the SSL enforcement admonition as it is no longer required. Sync engine can now be installed with or without SSL enforcement enabled. --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
111 lines
3.8 KiB
TypeScript
111 lines
3.8 KiB
TypeScript
import { useDatabaseExtensionsQuery } from 'data/database-extensions/database-extensions-query'
|
|
import { useSchemasQuery } from 'data/database/schemas-query'
|
|
import { useFDWsQuery } from 'data/fdw/fdws-query'
|
|
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
|
|
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
|
|
import { EMPTY_ARR } from 'lib/void'
|
|
import { useMemo } from 'react'
|
|
import { parseSchemaComment } from 'stripe-experiment-sync/supabase'
|
|
|
|
import { wrapperMetaComparator } from '../Wrappers/Wrappers.utils'
|
|
import { INTEGRATIONS } from './Integrations.constants'
|
|
import {
|
|
isInstalled as checkIsInstalled,
|
|
findStripeSchema,
|
|
} from '@/components/interfaces/Integrations/templates/StripeSyncEngine/stripe-sync-status'
|
|
|
|
export const useInstalledIntegrations = () => {
|
|
const { data: project } = useSelectedProjectQuery()
|
|
const { integrationsWrappers } = useIsFeatureEnabled(['integrations:wrappers'])
|
|
|
|
const allIntegrations = useMemo(() => {
|
|
return INTEGRATIONS.filter((integration) => {
|
|
if (
|
|
!integrationsWrappers &&
|
|
(integration.type === 'wrapper' || integration.id.endsWith('_wrapper'))
|
|
) {
|
|
return false
|
|
}
|
|
return true
|
|
})
|
|
}, [integrationsWrappers])
|
|
|
|
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 === 'data_api') {
|
|
return true
|
|
}
|
|
if (integration.id === 'stripe_sync_engine') {
|
|
const stripeSchema = findStripeSchema(schemas)
|
|
const parsedSchema = parseSchemaComment(stripeSchema?.comment)
|
|
return checkIsInstalled(parsedSchema.status)
|
|
}
|
|
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])
|
|
|
|
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,
|
|
error,
|
|
isError,
|
|
isLoading,
|
|
isSuccess,
|
|
}
|
|
}
|