diff --git a/apps/studio/components/interfaces/Integrations/Wrappers/CreateWrapperSheet.tsx b/apps/studio/components/interfaces/Integrations/Wrappers/CreateWrapperSheet.tsx index 89a566af4bd..75d26e58a82 100644 --- a/apps/studio/components/interfaces/Integrations/Wrappers/CreateWrapperSheet.tsx +++ b/apps/studio/components/interfaces/Integrations/Wrappers/CreateWrapperSheet.tsx @@ -387,6 +387,8 @@ export const CreateWrapperSheet = ({ } onClick={() => onRemove(tableIndex)} - tooltip={{ - content: { - side: 'bottom', - text: `Remove ${table.table_name} foreign table`, - }, - }} + tooltip={{ content: { side: 'bottom', text: 'Remove foreign table' } }} /> diff --git a/apps/studio/components/interfaces/Integrations/Wrappers/WrapperRow.tsx b/apps/studio/components/interfaces/Integrations/Wrappers/WrapperRow.tsx index 5614f43da7f..bb13873456f 100644 --- a/apps/studio/components/interfaces/Integrations/Wrappers/WrapperRow.tsx +++ b/apps/studio/components/interfaces/Integrations/Wrappers/WrapperRow.tsx @@ -63,10 +63,15 @@ export const WrapperRow = ({ wrapper }: WrapperRowProps) => { {_tables?.map((table) => { - const target = table.table ?? table.object ?? table.src_key ?? table.table_name + const target = + (table.table as string | undefined) ?? + (table.object as string | undefined) ?? + (table.src_key as string | undefined) ?? + table.table_name + const tableId = table.id as string return ( -
+
{integration.icon({ className: 'p-0' })} @@ -83,7 +88,7 @@ export const WrapperRow = ({ wrapper }: WrapperRowProps) => { - + diff --git a/apps/studio/components/interfaces/Integrations/Wrappers/Wrappers.utils.ts b/apps/studio/components/interfaces/Integrations/Wrappers/Wrappers.utils.ts index 550ff8fc640..b7753dac263 100644 --- a/apps/studio/components/interfaces/Integrations/Wrappers/Wrappers.utils.ts +++ b/apps/studio/components/interfaces/Integrations/Wrappers/Wrappers.utils.ts @@ -20,7 +20,7 @@ export const getWrapperCreationFormSchema = (wrapperMeta: WrapperMeta) => { let wrapperSchema = { // Common validation for all wrappers server_name: z.string().min(1, 'Please provide a name for your server'), - } as Record + } as Record // Add wrapper specific options wrapperMeta.server.options.forEach((option) => { @@ -57,7 +57,7 @@ export const getEditionFormSchema = (wrapperMeta: WrapperMeta) => { tables: z .array(tableSchema, { required_error: 'Please provide at least one table' }) .min(1, 'Please provide at least one table'), - } as Record + } as Record // Add wrapper specific options wrapperMeta.server.options.forEach((option) => { @@ -81,7 +81,7 @@ export const getTableFormSchema = (table: Table) => { type: z.string().min(1, 'Required'), }) ), - } as Record + } as Record table.options.forEach((option) => { if (option.required) { @@ -108,6 +108,10 @@ export const getTableFormSchema = (table: Table) => { ) } +function isRecord(value: unknown): value is Record { + return typeof value === 'object' && value !== null +} + export const makeValidateRequired = (options: { name: string; required: boolean }[]) => { const requiredOptionsSet = new Set( options.filter((option) => option.required).map((option) => option.name) @@ -118,12 +122,12 @@ export const makeValidateRequired = (options: { name: string; required: boolean ) const requiredArrayOptions = Array.from(requiredArrayOptionsSet) - return (values: Record) => { + return (values: Record) => { const errors = Object.fromEntries( Object.entries(values) - .flatMap(([key, value]) => + .flatMap(([key, value]): [string, unknown][] => Array.isArray(value) - ? [[key, value], ...value.map((v, i) => [`${key}.${i}`, v])] + ? [[key, value], ...value.map((v, i): [string, unknown] => [`${key}.${i}`, v])] : [[key, value]] ) .filter(([_key, value]) => { @@ -132,6 +136,7 @@ export const makeValidateRequired = (options: { name: string; required: boolean if ( idx !== undefined && requiredOptionsSet.has(key) && + isRecord(value) && Object.keys(value).some((subKey) => requiredArrayOptionsSet.has(`${key}.${subKey}`)) ) { const arrayOption = requiredArrayOptions.find((option) => option.startsWith(`${key}.`)) @@ -166,7 +171,7 @@ export interface FormattedWrapperTable { schema_name: string table_name: string object?: string // From options object for Firebase/Stripe - [key: string]: any // For other dynamic options from table.options + [key: string]: unknown // For other dynamic options from table.options } export const formatWrapperTables = ( diff --git a/apps/studio/components/interfaces/Storage/AnalyticsBuckets/AnalyticsBucketDetails/NamespaceWithTables/index.tsx b/apps/studio/components/interfaces/Storage/AnalyticsBuckets/AnalyticsBucketDetails/NamespaceWithTables/index.tsx index 06d3ad3744b..45b9684a32d 100644 --- a/apps/studio/components/interfaces/Storage/AnalyticsBuckets/AnalyticsBucketDetails/NamespaceWithTables/index.tsx +++ b/apps/studio/components/interfaces/Storage/AnalyticsBuckets/AnalyticsBucketDetails/NamespaceWithTables/index.tsx @@ -137,13 +137,13 @@ export const NamespaceWithTables = ({ const missingTables = useMemo(() => { return (tablesData || []).filter( - (t) => !tables.find((table) => table.table.split('.')[1] === t) + (t) => !tables.find((table) => (table.table as string).split('.')[1] === t) ) }, [tablesData, tables]) // Get all tables (connected + missing) for display const allTables = useMemo(() => { - const connectedTableNames = tables.map((table) => table.table.split('.')[1]) + const connectedTableNames = tables.map((table) => (table.table as string).split('.')[1]) const allTableNames = [...new Set([...connectedTableNames, ...missingTables])] return allTableNames.map((tableName) => ({ diff --git a/apps/studio/components/interfaces/Storage/AnalyticsBuckets/AnalyticsBucketDetails/index.tsx b/apps/studio/components/interfaces/Storage/AnalyticsBuckets/AnalyticsBucketDetails/index.tsx index 3bb5374afb7..a8d50d0cc6f 100644 --- a/apps/studio/components/interfaces/Storage/AnalyticsBuckets/AnalyticsBucketDetails/index.tsx +++ b/apps/studio/components/interfaces/Storage/AnalyticsBuckets/AnalyticsBucketDetails/index.tsx @@ -121,11 +121,11 @@ export const AnalyticBucketDetails = () => { const isPollingForData = pollIntervalNamespaces > 0 || pollIntervalNamespaceTables > 0 const namespaces = useMemo(() => { - const fdwNamespaces = wrapperTables.map((t) => t.table.split('.')[0]) as string[] + const fdwNamespaces = wrapperTables.map((t) => (t.table as string).split('.')[0]) const namespaces = uniq([...fdwNamespaces, ...(namespacesData ?? [])]) return namespaces.map((namespace) => { - const tables = wrapperTables.filter((t) => t.table.split('.')[0] === namespace) + const tables = wrapperTables.filter((t) => (t.table as string).split('.')[0] === namespace) const schema = tables[0]?.schema return {