From 79278656691ba5e0c13f8ef15be243abe390de97 Mon Sep 17 00:00:00 2001 From: "kemal.earth" <606977+kemaldotearth@users.noreply.github.com> Date: Wed, 8 Oct 2025 08:52:25 +0100 Subject: [PATCH 01/13] feat(studio): auth overview usage section (#39207) * feat: add button to all reports and basic layout * feat: add last 24 hours indicator * feat: add active users tile * feat: working first row of usage stats * feat: add basic report charts for sign in and sign up * fix: change prev number to difference from before * feat: pass time range to view all reports link * fix: get static numbers to show * fix: type error * fix: exclude admin users from active users * fix: revert change as number stopped working * feat: testing latest sign ups table * chore: remove table redoing * feat: testing with renderers * feat: revert back to reportchartv2 * feat: make sure sign up and sign in charts are bar by default * fix: class name for default difference num * chore: bit of clean up * chore: tidy up constants file * chore: remove unused auth renderers * feat: single query instead of multiple tiny ones * fix: query fetching * feat: simplify how the query does averages * nit: small css bits --- .../Auth/Overview/OverviewLearnMore.tsx | 13 +- .../Auth/Overview/OverviewUsage.constants.ts | 105 +++++++++ .../Auth/Overview/OverviewUsage.tsx | 202 +++++++++++++++++- .../pages/project/[ref]/auth/overview.tsx | 9 +- 4 files changed, 315 insertions(+), 14 deletions(-) create mode 100644 apps/studio/components/interfaces/Auth/Overview/OverviewUsage.constants.ts diff --git a/apps/studio/components/interfaces/Auth/Overview/OverviewLearnMore.tsx b/apps/studio/components/interfaces/Auth/Overview/OverviewLearnMore.tsx index 09053d42ce704..14274aeb8e8c6 100644 --- a/apps/studio/components/interfaces/Auth/Overview/OverviewLearnMore.tsx +++ b/apps/studio/components/interfaces/Auth/Overview/OverviewLearnMore.tsx @@ -15,7 +15,7 @@ export const OverviewLearnMore = () => { { label: 'Docs', title: 'Authentication docs', - description: 'Read more on authentication and benefits of using Supabase policies.', + description: 'Read more on authentication and the benefits of using Supabase policies.', image: `${BASE_PATH}/img/auth-overview/auth-overview-docs.jpg`, actions: [ { @@ -68,8 +68,7 @@ export const OverviewLearnMore = () => { { label: 'Logs', title: 'Dive into the logs', - description: - 'Our authentication logs provide a deeper view into your auth requests and errors.', + description: 'Authentication logs provide a deeper view into your auth requests.', image: `${BASE_PATH}/img/auth-overview/auth-overview-logs.jpg`, actions: [ { @@ -84,7 +83,7 @@ export const OverviewLearnMore = () => { return ( Learn more -
+
{LearnMoreCards.map((card) => ( @@ -100,12 +99,12 @@ export const OverviewLearnMore = () => { className="object-fit" />
-
-
+
+

{card.title}

{card.description}

-
+
{card.actions.map((action) => { if ('href' in action) { return ( diff --git a/apps/studio/components/interfaces/Auth/Overview/OverviewUsage.constants.ts b/apps/studio/components/interfaces/Auth/Overview/OverviewUsage.constants.ts new file mode 100644 index 0000000000000..caad4e200302b --- /dev/null +++ b/apps/studio/components/interfaces/Auth/Overview/OverviewUsage.constants.ts @@ -0,0 +1,105 @@ +import dayjs from 'dayjs' +import { fetchLogs } from 'data/reports/report.utils' + +// Date range helpers +export const getDateRanges = () => { + const endDate = dayjs().toISOString() + const startDate = dayjs().subtract(24, 'hour').toISOString() + const previousEndDate = dayjs().subtract(24, 'hour').toISOString() + const previousStartDate = dayjs().subtract(48, 'hour').toISOString() + + return { + current: { startDate, endDate }, + previous: { startDate: previousStartDate, endDate: previousEndDate }, + } +} + +export const AUTH_COMBINED_QUERY = () => ` + with base as ( + select + json_value(event_message, "$.auth_event.action") as action, + json_value(event_message, "$.auth_event.actor_id") as actor_id, + cast(json_value(event_message, "$.duration") as int64) as duration_ns + from auth_logs + ) + + select + 'activeUsers' as metric, + cast(count(distinct case + when action in ( + 'login','user_signedup','token_refreshed','user_modified', + 'user_recovery_requested','user_reauthenticate_requested' + ) then actor_id + else null + end) as float64) as value + from base + + union all + select 'passwordResetRequests' as metric, + cast(count(case when action = 'user_recovery_requested' then 1 else null end) as float64) + from base + + union all + select 'signUpCount' as metric, + cast(count(case when action = 'user_signedup' then 1 else null end) as float64) + from base + + union all + select 'signInLatency' as metric, + coalesce(round(avg(case when action = 'login' then duration_ns else null end) / 1000000, 2), 0) + from base + + union all + select 'signUpLatency' as metric, + coalesce(round(avg(case when action = 'user_signedup' then duration_ns else null end) / 1000000, 2), 0) + from base +` + +export const fetchAllAuthMetrics = async (projectRef: string, period: 'current' | 'previous') => { + const sql = AUTH_COMBINED_QUERY() + const { current, previous } = getDateRanges() + const dateRange = period === 'current' ? current : previous + + return await fetchLogs(projectRef, sql, dateRange.startDate, dateRange.endDate) +} + +export const processAllAuthMetrics = (currentData: any[], previousData: any[]) => { + const processData = (data: any[]) => { + if (!data || !Array.isArray(data)) { + return { activeUsers: 0, passwordResets: 0, signInLatency: 0, signUpLatency: 0 } + } + + const result = data.reduce( + (acc, row) => { + const { metric, value } = row + if (metric === 'activeUsers') acc.activeUsers = value || 0 + if (metric === 'passwordResetRequests') acc.passwordResets = value || 0 + if (metric === 'signInLatency') acc.signInLatency = value || 0 + if (metric === 'signUpLatency') acc.signUpLatency = value || 0 + return acc + }, + { activeUsers: 0, passwordResets: 0, signInLatency: 0, signUpLatency: 0 } + ) + + return result + } + + return { + current: processData(currentData), + previous: processData(previousData), + } +} + +// Utility functions +export const calculatePercentageChange = (current: number, previous: number): number => { + if (previous === 0) return current > 0 ? 100 : 0 + return ((current - previous) / previous) * 100 +} + +export const getChangeColor = (percentageChange: number): string => { + return percentageChange >= 0 ? 'text-brand' : 'text-destructive' +} + +export const getChangeSign = (percentageChange: number): string => { + return percentageChange >= 0 ? '+' : '' +} diff --git a/apps/studio/components/interfaces/Auth/Overview/OverviewUsage.tsx b/apps/studio/components/interfaces/Auth/Overview/OverviewUsage.tsx index f0223bd5091a5..dac8b7b29aba9 100644 --- a/apps/studio/components/interfaces/Auth/Overview/OverviewUsage.tsx +++ b/apps/studio/components/interfaces/Auth/Overview/OverviewUsage.tsx @@ -1,14 +1,204 @@ -import { ScaffoldSection, ScaffoldSectionTitle } from 'components/layouts/Scaffold' -import { Card } from 'ui' +import { + ScaffoldSection, + ScaffoldSectionTitle, + ScaffoldSectionContent, +} from 'components/layouts/Scaffold' +import { Card, CardContent, cn } from 'ui' +import Link from 'next/link' +import { useParams } from 'common' +import { ChevronRight, Loader2 } from 'lucide-react' +import { Reports } from 'icons' +import { + getChangeSign, + getChangeColor, + fetchAllAuthMetrics, + processAllAuthMetrics, + calculatePercentageChange, +} from './OverviewUsage.constants' +import { useQuery } from '@tanstack/react-query' +import { useMemo } from 'react' +import { ReportChartV2 } from 'components/interfaces/Reports/v2/ReportChartV2' +import { createAuthReportConfig } from 'data/reports/v2/auth.config' +import dayjs from 'dayjs' + +const StatCard = ({ + title, + current, + previous, + loading, + suffix = '', +}: { + title: string + current: number + previous: number + loading: boolean + suffix?: string +}) => { + const changeColor = getChangeColor(previous) + const changeSign = getChangeSign(previous) + const formattedCurrent = suffix === 'ms' ? current.toFixed(2) : current + + return ( + + + {loading ? ( + + ) : ( + <> +

{title}

+

{`${formattedCurrent}${suffix}`}

+

+ {`${changeSign}${previous.toFixed(1)}%`} +

+ + )} +
+
+ ) +} export const OverviewUsage = () => { + const { ref } = useParams() + + const { data: currentData, isLoading: currentLoading } = useQuery({ + queryKey: ['auth-metrics', ref, 'current'], + queryFn: () => fetchAllAuthMetrics(ref as string, 'current'), + enabled: !!ref, + }) + + const { data: previousData, isLoading: previousLoading } = useQuery({ + queryKey: ['auth-metrics', ref, 'previous'], + queryFn: () => fetchAllAuthMetrics(ref as string, 'previous'), + enabled: !!ref, + }) + + const metrics = processAllAuthMetrics(currentData?.result || [], previousData?.result || []) + const isLoading = currentLoading || previousLoading + + const activeUsersChange = calculatePercentageChange( + metrics.current.activeUsers, + metrics.previous.activeUsers + ) + const passwordResetChange = calculatePercentageChange( + metrics.current.passwordResets, + metrics.previous.passwordResets + ) + const signInLatencyChange = calculatePercentageChange( + metrics.current.signInLatency, + metrics.previous.signInLatency + ) + const signUpLatencyChange = calculatePercentageChange( + metrics.current.signUpLatency, + metrics.previous.signUpLatency + ) + + const endDate = dayjs().toISOString() + const startDate = dayjs().subtract(24, 'hour').toISOString() + + const signUpChartConfig = useMemo(() => { + const config = createAuthReportConfig({ + projectRef: ref as string, + startDate, + endDate, + interval: '1h', + filters: { status_code: null }, + }) + const chart = config.find((c) => c.id === 'signups') + if (chart) { + return { ...chart, defaultChartStyle: 'bar' } + } + return chart + }, [ref, startDate, endDate]) + + const signInChartConfig = useMemo(() => { + const config = createAuthReportConfig({ + projectRef: ref as string, + startDate, + endDate, + interval: '1h', + filters: { status_code: null }, + }) + const chart = config.find((c) => c.id === 'sign-in-attempts') + if (chart) { + return { ...chart, defaultChartStyle: 'bar' } + } + return chart + }, [ref, startDate, endDate]) + + const updateDateRange = (from: string, to: string) => { + console.log('Date range update:', from, to) + } + return ( - Usage -
- - +
+ Usage + + + View all reports + +
+ +
+ + + + +
+
+ {signUpChartConfig && ( + + )} + {signInChartConfig && ( + + )} +
+
) } diff --git a/apps/studio/pages/project/[ref]/auth/overview.tsx b/apps/studio/pages/project/[ref]/auth/overview.tsx index 6f55feeb6c7e1..86f8f300fe14a 100644 --- a/apps/studio/pages/project/[ref]/auth/overview.tsx +++ b/apps/studio/pages/project/[ref]/auth/overview.tsx @@ -45,7 +45,14 @@ AuthOverview.getLayout = (page) => ( } + secondaryActions={ +
+ + All reports Last 24 hours + + +
+ } size="large" > {page} From 799f6c4139aa3875fc62ed40b4365e90f15f742e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:46:19 +0300 Subject: [PATCH 02/13] feat: update @supabase/*-js libraries to v2.74.0 (#39326) * feat: update @supabase/*-js libraries to v2.74.0 * Use catalog supabase/supabase-js in all apps/packages. * Bump supabase/ssr to 0.7.0. * Fix edge cases for the infinite query hook. * Remove extra packages, they're covered under the next rule. --------- Co-authored-by: mandarini <6603745+mandarini@users.noreply.github.com> Co-authored-by: Ivan Vasilov --- apps/ui-library/package.json | 4 +- .../hooks/use-infinite-query.ts | 16 +- .../default/fixtures/database.types.ts | 671 ++++++++++++++++-- blocks/vue/package.json | 4 +- pnpm-lock.yaml | 125 ++-- pnpm-workspace.yaml | 6 +- 6 files changed, 681 insertions(+), 145 deletions(-) diff --git a/apps/ui-library/package.json b/apps/ui-library/package.json index fb1de24492315..c398bbeeb9f8f 100644 --- a/apps/ui-library/package.json +++ b/apps/ui-library/package.json @@ -90,8 +90,8 @@ "devDependencies": { "@react-router/dev": "^7.1.5", "@shikijs/compat": "^1.1.7", - "@supabase/ssr": "^0.6.1", - "@supabase/supabase-js": "^2.49.1", + "@supabase/ssr": "^0.7.0", + "@supabase/supabase-js": "catalog:", "@tanstack/react-router": "^1.114.27", "@tanstack/react-start": "^1.114.25", "@types/common-tags": "^1.8.4", diff --git a/apps/ui-library/registry/default/blocks/infinite-query-hook/hooks/use-infinite-query.ts b/apps/ui-library/registry/default/blocks/infinite-query-hook/hooks/use-infinite-query.ts index 685b207407cfc..93a8fe00f8b72 100644 --- a/apps/ui-library/registry/default/blocks/infinite-query-hook/hooks/use-infinite-query.ts +++ b/apps/ui-library/registry/default/blocks/infinite-query-hook/hooks/use-infinite-query.ts @@ -2,7 +2,7 @@ import { createClient } from '@/registry/default/fixtures/lib/supabase/client' import { PostgrestQueryBuilder } from '@supabase/postgrest-js' -import { SupabaseClient } from '@supabase/supabase-js' +import { type SupabaseClient } from '@supabase/supabase-js' import { useEffect, useRef, useSyncExternalStore } from 'react' const supabase = createClient() @@ -27,7 +27,13 @@ type Database = }, U > - : never + : { + public: { + Tables: Record + Views: Record + Functions: Record + } + } // Change this to the database schema you want to use type DatabaseSchema = Database['public'] @@ -114,12 +120,8 @@ function createStore, T extends SupabaseTable console.error('An unexpected error occurred:', error) setState({ error }) } else { - const deduplicatedData = ((newData || []) as TData[]).filter( - (item) => !state.data.find((old) => old.id === item.id) - ) - setState({ - data: [...state.data, ...deduplicatedData], + data: [...state.data, ...(newData as TData[])], count: count || 0, isSuccess: true, error: null, diff --git a/apps/ui-library/registry/default/fixtures/database.types.ts b/apps/ui-library/registry/default/fixtures/database.types.ts index 8736e8411052b..0f5b655d220c0 100644 --- a/apps/ui-library/registry/default/fixtures/database.types.ts +++ b/apps/ui-library/registry/default/fixtures/database.types.ts @@ -50,7 +50,15 @@ export type Database = { task?: string | null user_id?: string } - Relationships: [] + Relationships: [ + { + foreignKeyName: 'todos_user_id_fkey' + columns: ['user_id'] + isOneToOne: false + referencedRelation: 'users' + referencedColumns: ['id'] + }, + ] } } Views: { @@ -66,29 +74,588 @@ export type Database = { [_ in never]: never } } + storage: { + Tables: { + buckets: { + Row: { + allowed_mime_types: string[] | null + avif_autodetection: boolean | null + created_at: string | null + file_size_limit: number | null + id: string + name: string + owner: string | null + owner_id: string | null + public: boolean | null + type: Database['storage']['Enums']['buckettype'] + updated_at: string | null + } + Insert: { + allowed_mime_types?: string[] | null + avif_autodetection?: boolean | null + created_at?: string | null + file_size_limit?: number | null + id: string + name: string + owner?: string | null + owner_id?: string | null + public?: boolean | null + type?: Database['storage']['Enums']['buckettype'] + updated_at?: string | null + } + Update: { + allowed_mime_types?: string[] | null + avif_autodetection?: boolean | null + created_at?: string | null + file_size_limit?: number | null + id?: string + name?: string + owner?: string | null + owner_id?: string | null + public?: boolean | null + type?: Database['storage']['Enums']['buckettype'] + updated_at?: string | null + } + Relationships: [] + } + buckets_analytics: { + Row: { + created_at: string + format: string + id: string + type: Database['storage']['Enums']['buckettype'] + updated_at: string + } + Insert: { + created_at?: string + format?: string + id: string + type?: Database['storage']['Enums']['buckettype'] + updated_at?: string + } + Update: { + created_at?: string + format?: string + id?: string + type?: Database['storage']['Enums']['buckettype'] + updated_at?: string + } + Relationships: [] + } + iceberg_namespaces: { + Row: { + bucket_id: string + created_at: string + id: string + name: string + updated_at: string + } + Insert: { + bucket_id: string + created_at?: string + id?: string + name: string + updated_at?: string + } + Update: { + bucket_id?: string + created_at?: string + id?: string + name?: string + updated_at?: string + } + Relationships: [ + { + foreignKeyName: 'iceberg_namespaces_bucket_id_fkey' + columns: ['bucket_id'] + isOneToOne: false + referencedRelation: 'buckets_analytics' + referencedColumns: ['id'] + }, + ] + } + iceberg_tables: { + Row: { + bucket_id: string + created_at: string + id: string + location: string + name: string + namespace_id: string + updated_at: string + } + Insert: { + bucket_id: string + created_at?: string + id?: string + location: string + name: string + namespace_id: string + updated_at?: string + } + Update: { + bucket_id?: string + created_at?: string + id?: string + location?: string + name?: string + namespace_id?: string + updated_at?: string + } + Relationships: [ + { + foreignKeyName: 'iceberg_tables_bucket_id_fkey' + columns: ['bucket_id'] + isOneToOne: false + referencedRelation: 'buckets_analytics' + referencedColumns: ['id'] + }, + { + foreignKeyName: 'iceberg_tables_namespace_id_fkey' + columns: ['namespace_id'] + isOneToOne: false + referencedRelation: 'iceberg_namespaces' + referencedColumns: ['id'] + }, + ] + } + migrations: { + Row: { + executed_at: string | null + hash: string + id: number + name: string + } + Insert: { + executed_at?: string | null + hash: string + id: number + name: string + } + Update: { + executed_at?: string | null + hash?: string + id?: number + name?: string + } + Relationships: [] + } + objects: { + Row: { + bucket_id: string | null + created_at: string | null + id: string + last_accessed_at: string | null + level: number | null + metadata: Json | null + name: string | null + owner: string | null + owner_id: string | null + path_tokens: string[] | null + updated_at: string | null + user_metadata: Json | null + version: string | null + } + Insert: { + bucket_id?: string | null + created_at?: string | null + id?: string + last_accessed_at?: string | null + level?: number | null + metadata?: Json | null + name?: string | null + owner?: string | null + owner_id?: string | null + path_tokens?: string[] | null + updated_at?: string | null + user_metadata?: Json | null + version?: string | null + } + Update: { + bucket_id?: string | null + created_at?: string | null + id?: string + last_accessed_at?: string | null + level?: number | null + metadata?: Json | null + name?: string | null + owner?: string | null + owner_id?: string | null + path_tokens?: string[] | null + updated_at?: string | null + user_metadata?: Json | null + version?: string | null + } + Relationships: [ + { + foreignKeyName: 'objects_bucketId_fkey' + columns: ['bucket_id'] + isOneToOne: false + referencedRelation: 'buckets' + referencedColumns: ['id'] + }, + ] + } + prefixes: { + Row: { + bucket_id: string + created_at: string | null + level: number + name: string + updated_at: string | null + } + Insert: { + bucket_id: string + created_at?: string | null + level?: number + name: string + updated_at?: string | null + } + Update: { + bucket_id?: string + created_at?: string | null + level?: number + name?: string + updated_at?: string | null + } + Relationships: [ + { + foreignKeyName: 'prefixes_bucketId_fkey' + columns: ['bucket_id'] + isOneToOne: false + referencedRelation: 'buckets' + referencedColumns: ['id'] + }, + ] + } + s3_multipart_uploads: { + Row: { + bucket_id: string + created_at: string + id: string + in_progress_size: number + key: string + owner_id: string | null + upload_signature: string + user_metadata: Json | null + version: string + } + Insert: { + bucket_id: string + created_at?: string + id: string + in_progress_size?: number + key: string + owner_id?: string | null + upload_signature: string + user_metadata?: Json | null + version: string + } + Update: { + bucket_id?: string + created_at?: string + id?: string + in_progress_size?: number + key?: string + owner_id?: string | null + upload_signature?: string + user_metadata?: Json | null + version?: string + } + Relationships: [ + { + foreignKeyName: 's3_multipart_uploads_bucket_id_fkey' + columns: ['bucket_id'] + isOneToOne: false + referencedRelation: 'buckets' + referencedColumns: ['id'] + }, + ] + } + s3_multipart_uploads_parts: { + Row: { + bucket_id: string + created_at: string + etag: string + id: string + key: string + owner_id: string | null + part_number: number + size: number + upload_id: string + version: string + } + Insert: { + bucket_id: string + created_at?: string + etag: string + id?: string + key: string + owner_id?: string | null + part_number: number + size?: number + upload_id: string + version: string + } + Update: { + bucket_id?: string + created_at?: string + etag?: string + id?: string + key?: string + owner_id?: string | null + part_number?: number + size?: number + upload_id?: string + version?: string + } + Relationships: [ + { + foreignKeyName: 's3_multipart_uploads_parts_bucket_id_fkey' + columns: ['bucket_id'] + isOneToOne: false + referencedRelation: 'buckets' + referencedColumns: ['id'] + }, + { + foreignKeyName: 's3_multipart_uploads_parts_upload_id_fkey' + columns: ['upload_id'] + isOneToOne: false + referencedRelation: 's3_multipart_uploads' + referencedColumns: ['id'] + }, + ] + } + } + Views: { + [_ in never]: never + } + Functions: { + add_prefixes: { + Args: { + _bucket_id: string + _name: string + } + Returns: undefined + } + can_insert_object: { + Args: { + bucketid: string + name: string + owner: string + metadata: Json + } + Returns: undefined + } + delete_leaf_prefixes: { + Args: { + bucket_ids: string[] + names: string[] + } + Returns: undefined + } + delete_prefix: { + Args: { + _bucket_id: string + _name: string + } + Returns: boolean + } + extension: { + Args: { + name: string + } + Returns: string + } + filename: { + Args: { + name: string + } + Returns: string + } + foldername: { + Args: { + name: string + } + Returns: string[] + } + get_level: { + Args: { + name: string + } + Returns: number + } + get_prefix: { + Args: { + name: string + } + Returns: string + } + get_prefixes: { + Args: { + name: string + } + Returns: string[] + } + get_size_by_bucket: { + Args: Record + Returns: { + size: number + bucket_id: string + }[] + } + list_multipart_uploads_with_delimiter: { + Args: { + bucket_id: string + prefix_param: string + delimiter_param: string + max_keys?: number + next_key_token?: string + next_upload_token?: string + } + Returns: { + key: string + id: string + created_at: string + }[] + } + list_objects_with_delimiter: { + Args: { + bucket_id: string + prefix_param: string + delimiter_param: string + max_keys?: number + start_after?: string + next_token?: string + } + Returns: { + name: string + id: string + metadata: Json + updated_at: string + }[] + } + lock_top_prefixes: { + Args: { + bucket_ids: string[] + names: string[] + } + Returns: undefined + } + operation: { + Args: Record + Returns: string + } + search: { + Args: { + prefix: string + bucketname: string + limits?: number + levels?: number + offsets?: number + search?: string + sortcolumn?: string + sortorder?: string + } + Returns: { + name: string + id: string + updated_at: string + created_at: string + last_accessed_at: string + metadata: Json + }[] + } + search_legacy_v1: { + Args: { + prefix: string + bucketname: string + limits?: number + levels?: number + offsets?: number + search?: string + sortcolumn?: string + sortorder?: string + } + Returns: { + name: string + id: string + updated_at: string + created_at: string + last_accessed_at: string + metadata: Json + }[] + } + search_v1_optimised: { + Args: { + prefix: string + bucketname: string + limits?: number + levels?: number + offsets?: number + search?: string + sortcolumn?: string + sortorder?: string + } + Returns: { + name: string + id: string + updated_at: string + created_at: string + last_accessed_at: string + metadata: Json + }[] + } + search_v2: { + Args: { + prefix: string + bucket_name: string + limits?: number + levels?: number + start_after?: string + sort_order?: string + sort_column?: string + sort_column_after?: string + } + Returns: { + key: string + name: string + id: string + updated_at: string + created_at: string + last_accessed_at: string + metadata: Json + }[] + } + } + Enums: { + buckettype: 'STANDARD' | 'ANALYTICS' + } + CompositeTypes: { + [_ in never]: never + } + } } -type DefaultSchema = Database[Extract] +type PublicSchema = Database[Extract] export type Tables< - DefaultSchemaTableNameOrOptions extends - | keyof (DefaultSchema['Tables'] & DefaultSchema['Views']) + PublicTableNameOrOptions extends + | keyof (PublicSchema['Tables'] & PublicSchema['Views']) | { schema: keyof Database }, - TableName extends DefaultSchemaTableNameOrOptions extends { - schema: keyof Database - } - ? keyof (Database[DefaultSchemaTableNameOrOptions['schema']]['Tables'] & - Database[DefaultSchemaTableNameOrOptions['schema']]['Views']) + TableName extends PublicTableNameOrOptions extends { schema: keyof Database } + ? keyof (Database[PublicTableNameOrOptions['schema']]['Tables'] & + Database[PublicTableNameOrOptions['schema']]['Views']) : never = never, -> = DefaultSchemaTableNameOrOptions extends { schema: keyof Database } - ? (Database[DefaultSchemaTableNameOrOptions['schema']]['Tables'] & - Database[DefaultSchemaTableNameOrOptions['schema']]['Views'])[TableName] extends { +> = PublicTableNameOrOptions extends { schema: keyof Database } + ? (Database[PublicTableNameOrOptions['schema']]['Tables'] & + Database[PublicTableNameOrOptions['schema']]['Views'])[TableName] extends { Row: infer R } ? R : never - : DefaultSchemaTableNameOrOptions extends keyof (DefaultSchema['Tables'] & DefaultSchema['Views']) - ? (DefaultSchema['Tables'] & DefaultSchema['Views'])[DefaultSchemaTableNameOrOptions] extends { + : PublicTableNameOrOptions extends keyof (PublicSchema['Tables'] & PublicSchema['Views']) + ? (PublicSchema['Tables'] & PublicSchema['Views'])[PublicTableNameOrOptions] extends { Row: infer R } ? R @@ -96,22 +663,18 @@ export type Tables< : never export type TablesInsert< - DefaultSchemaTableNameOrOptions extends - | keyof DefaultSchema['Tables'] - | { schema: keyof Database }, - TableName extends DefaultSchemaTableNameOrOptions extends { - schema: keyof Database - } - ? keyof Database[DefaultSchemaTableNameOrOptions['schema']]['Tables'] + PublicTableNameOrOptions extends keyof PublicSchema['Tables'] | { schema: keyof Database }, + TableName extends PublicTableNameOrOptions extends { schema: keyof Database } + ? keyof Database[PublicTableNameOrOptions['schema']]['Tables'] : never = never, -> = DefaultSchemaTableNameOrOptions extends { schema: keyof Database } - ? Database[DefaultSchemaTableNameOrOptions['schema']]['Tables'][TableName] extends { +> = PublicTableNameOrOptions extends { schema: keyof Database } + ? Database[PublicTableNameOrOptions['schema']]['Tables'][TableName] extends { Insert: infer I } ? I : never - : DefaultSchemaTableNameOrOptions extends keyof DefaultSchema['Tables'] - ? DefaultSchema['Tables'][DefaultSchemaTableNameOrOptions] extends { + : PublicTableNameOrOptions extends keyof PublicSchema['Tables'] + ? PublicSchema['Tables'][PublicTableNameOrOptions] extends { Insert: infer I } ? I @@ -119,22 +682,18 @@ export type TablesInsert< : never export type TablesUpdate< - DefaultSchemaTableNameOrOptions extends - | keyof DefaultSchema['Tables'] - | { schema: keyof Database }, - TableName extends DefaultSchemaTableNameOrOptions extends { - schema: keyof Database - } - ? keyof Database[DefaultSchemaTableNameOrOptions['schema']]['Tables'] + PublicTableNameOrOptions extends keyof PublicSchema['Tables'] | { schema: keyof Database }, + TableName extends PublicTableNameOrOptions extends { schema: keyof Database } + ? keyof Database[PublicTableNameOrOptions['schema']]['Tables'] : never = never, -> = DefaultSchemaTableNameOrOptions extends { schema: keyof Database } - ? Database[DefaultSchemaTableNameOrOptions['schema']]['Tables'][TableName] extends { +> = PublicTableNameOrOptions extends { schema: keyof Database } + ? Database[PublicTableNameOrOptions['schema']]['Tables'][TableName] extends { Update: infer U } ? U : never - : DefaultSchemaTableNameOrOptions extends keyof DefaultSchema['Tables'] - ? DefaultSchema['Tables'][DefaultSchemaTableNameOrOptions] extends { + : PublicTableNameOrOptions extends keyof PublicSchema['Tables'] + ? PublicSchema['Tables'][PublicTableNameOrOptions] extends { Update: infer U } ? U @@ -142,38 +701,12 @@ export type TablesUpdate< : never export type Enums< - DefaultSchemaEnumNameOrOptions extends keyof DefaultSchema['Enums'] | { schema: keyof Database }, - EnumName extends DefaultSchemaEnumNameOrOptions extends { - schema: keyof Database - } - ? keyof Database[DefaultSchemaEnumNameOrOptions['schema']]['Enums'] + PublicEnumNameOrOptions extends keyof PublicSchema['Enums'] | { schema: keyof Database }, + EnumName extends PublicEnumNameOrOptions extends { schema: keyof Database } + ? keyof Database[PublicEnumNameOrOptions['schema']]['Enums'] : never = never, -> = DefaultSchemaEnumNameOrOptions extends { schema: keyof Database } - ? Database[DefaultSchemaEnumNameOrOptions['schema']]['Enums'][EnumName] - : DefaultSchemaEnumNameOrOptions extends keyof DefaultSchema['Enums'] - ? DefaultSchema['Enums'][DefaultSchemaEnumNameOrOptions] +> = PublicEnumNameOrOptions extends { schema: keyof Database } + ? Database[PublicEnumNameOrOptions['schema']]['Enums'][EnumName] + : PublicEnumNameOrOptions extends keyof PublicSchema['Enums'] + ? PublicSchema['Enums'][PublicEnumNameOrOptions] : never - -export type CompositeTypes< - PublicCompositeTypeNameOrOptions extends - | keyof DefaultSchema['CompositeTypes'] - | { schema: keyof Database }, - CompositeTypeName extends PublicCompositeTypeNameOrOptions extends { - schema: keyof Database - } - ? keyof Database[PublicCompositeTypeNameOrOptions['schema']]['CompositeTypes'] - : never = never, -> = PublicCompositeTypeNameOrOptions extends { schema: keyof Database } - ? Database[PublicCompositeTypeNameOrOptions['schema']]['CompositeTypes'][CompositeTypeName] - : PublicCompositeTypeNameOrOptions extends keyof DefaultSchema['CompositeTypes'] - ? DefaultSchema['CompositeTypes'][PublicCompositeTypeNameOrOptions] - : never - -export const Constants = { - graphql_public: { - Enums: {}, - }, - public: { - Enums: {}, - }, -} as const diff --git a/blocks/vue/package.json b/blocks/vue/package.json index 1352ff7996761..d7f3213264d74 100644 --- a/blocks/vue/package.json +++ b/blocks/vue/package.json @@ -12,8 +12,8 @@ "dependencies": { "h3": "^1.15.4", "nuxt": "^4.0.3", - "@supabase/ssr": "^0.6.1", - "@supabase/supabase-js": "^2.49.1" + "@supabase/ssr": "^0.7.0", + "@supabase/supabase-js": "catalog:" }, "devDependencies": { "shadcn": "^3.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 691c7ece6bd70..4944220ab4d5c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,14 +7,14 @@ settings: catalogs: default: '@supabase/auth-js': - specifier: 2.72.0-rc.11 - version: 2.72.0-rc.11 + specifier: 2.74.0 + version: 2.74.0 '@supabase/realtime-js': - specifier: ^2.11.3 - version: 2.11.3 + specifier: 2.74.0 + version: 2.74.0 '@supabase/supabase-js': - specifier: ^2.47.14 - version: 2.49.3 + specifier: 2.74.0 + version: 2.74.0 '@types/node': specifier: ^22.0.0 version: 22.13.14 @@ -51,7 +51,7 @@ catalogs: overrides: '@redocly/respect-core>form-data': ^4.0.4 - '@supabase/supabase-js>@supabase/auth-js': 2.72.0-rc.11 + '@supabase/supabase-js>@supabase/auth-js': 2.74.0 '@tanstack/directive-functions-plugin>vite': ^6.3.6 '@tanstack/react-start-plugin>vite': ^6.3.6 esbuild: ^0.25.2 @@ -388,7 +388,7 @@ importers: version: 10.3.0(@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.5.2(@babel/core@7.28.4(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0) '@supabase/supabase-js': specifier: 'catalog:' - version: 2.49.3 + version: 2.74.0 '@tailwindcss/container-queries': specifier: ^0.1.1 version: 0.1.1(tailwindcss@4.1.13) @@ -812,7 +812,7 @@ importers: version: 7.5.0 '@supabase/auth-js': specifier: 'catalog:' - version: 2.72.0-rc.11 + version: 2.74.0 '@supabase/mcp-server-supabase': specifier: ^0.5.4 version: 0.5.5(supports-color@8.1.1) @@ -824,7 +824,7 @@ importers: version: link:../../packages/pg-meta '@supabase/realtime-js': specifier: 'catalog:' - version: 2.11.3 + version: 2.74.0 '@supabase/shared-types': specifier: 0.1.80 version: 0.1.80 @@ -833,7 +833,7 @@ importers: version: 0.1.6(encoding@0.1.13)(supports-color@8.1.1) '@supabase/supabase-js': specifier: 'catalog:' - version: 2.49.3 + version: 2.74.0 '@tanstack/react-query': specifier: 4.35.7 version: 4.35.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -1473,11 +1473,11 @@ importers: specifier: ^1.1.7 version: 1.6.0 '@supabase/ssr': - specifier: ^0.6.1 - version: 0.6.1(@supabase/supabase-js@2.49.3) + specifier: ^0.7.0 + version: 0.7.0(@supabase/supabase-js@2.74.0) '@supabase/supabase-js': - specifier: ^2.49.1 - version: 2.49.3 + specifier: 'catalog:' + version: 2.74.0 '@tanstack/react-router': specifier: ^1.114.27 version: 1.114.27(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -1588,7 +1588,7 @@ importers: version: 10.3.0(@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.5.2(@babel/core@7.28.4(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.53.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0) '@supabase/supabase-js': specifier: 'catalog:' - version: 2.49.3 + version: 2.74.0 '@vercel/og': specifier: ^0.6.2 version: 0.6.2 @@ -1816,11 +1816,11 @@ importers: blocks/vue: dependencies: '@supabase/ssr': - specifier: ^0.6.1 - version: 0.6.1(@supabase/supabase-js@2.49.3) + specifier: ^0.7.0 + version: 0.7.0(@supabase/supabase-js@2.74.0) '@supabase/supabase-js': - specifier: ^2.49.1 - version: 2.49.3 + specifier: 'catalog:' + version: 2.74.0 h3: specifier: ^1.15.4 version: 1.15.4 @@ -1854,7 +1854,7 @@ importers: version: 0.18.5 '@supabase/supabase-js': specifier: 'catalog:' - version: 2.49.3 + version: 2.74.0 ai: specifier: ^5.0.0 version: 5.0.2(zod@3.25.76) @@ -1948,10 +1948,10 @@ importers: dependencies: '@supabase/auth-js': specifier: 'catalog:' - version: 2.72.0-rc.11 + version: 2.74.0 '@supabase/supabase-js': specifier: 'catalog:' - version: 2.49.3 + version: 2.74.0 '@types/dat.gui': specifier: ^0.7.12 version: 0.7.12 @@ -2402,7 +2402,7 @@ importers: version: 0.1.6(encoding@0.1.13)(supports-color@8.1.1) '@supabase/supabase-js': specifier: 'catalog:' - version: 2.49.3 + version: 2.74.0 '@vitest/coverage-v8': specifier: ^3.0.9 version: 3.0.9(supports-color@8.1.1)(vitest@3.0.9(@types/node@22.13.14)(jiti@2.5.1)(jsdom@20.0.3(supports-color@8.1.1))(msw@2.11.3(@types/node@22.13.14)(typescript@5.9.2))(sass@1.77.4)(supports-color@8.1.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.8.1)) @@ -8846,11 +8846,11 @@ packages: resolution: {integrity: sha512-Cq3KKe+G1o7PSBMbmrgpT2JgBeyH2THHr3RdIX2MqF7AnBuspIMgtZ3ktcCgP7kZsTMvnmWymr7zZCT1zeWbMw==} engines: {node: '>=12.16'} - '@supabase/auth-js@2.72.0-rc.11': - resolution: {integrity: sha512-7C0xC6ZXbIB8GAoO6saWNMRhKox9OeYvMmpfPJyxFiECg9z78SMhMotiyI3U1Ws47iGiaDonEUnuxDuHAG04nQ==} + '@supabase/auth-js@2.74.0': + resolution: {integrity: sha512-EJYDxYhBCOS40VJvfQ5zSjo8Ku7JbTICLTcmXt4xHMQZt4IumpRfHg11exXI9uZ6G7fhsQlNgbzDhFN4Ni9NnA==} - '@supabase/functions-js@2.4.4': - resolution: {integrity: sha512-WL2p6r4AXNGwop7iwvul2BvOtuJ1YQy8EbOd0dhG1oN1q8el/BIRSFCFnWAMM/vJJlHWLi4ad22sKbKr9mvjoA==} + '@supabase/functions-js@2.74.0': + resolution: {integrity: sha512-VqWYa981t7xtIFVf7LRb9meklHckbH/tqwaML5P3LgvlaZHpoSPjMCNLcquuLYiJLxnh2rio7IxLh+VlvRvSWw==} '@supabase/mcp-server-supabase@0.5.5': resolution: {integrity: sha512-te1XM2i+h3NBUgJ/8z9PkNCKaJ268VzFI3Qx5RA97s8eGtH94NyPy3lOIZAh3BFAOFHDpcB7Mn1b0oCTGFxg5g==} @@ -8873,11 +8873,11 @@ packages: '@supabase/postgrest-js@1.19.2': resolution: {integrity: sha512-MXRbk4wpwhWl9IN6rIY1mR8uZCCG4MZAEji942ve6nMwIqnBgBnZhZlON6zTTs6fgveMnoCILpZv1+K91jN+ow==} - '@supabase/realtime-js@2.11.2': - resolution: {integrity: sha512-u/XeuL2Y0QEhXSoIPZZwR6wMXgB+RQbJzG9VErA3VghVt7uRfSVsjeqd7m5GhX3JR6dM/WRmLbVR8URpDWG4+w==} + '@supabase/postgrest-js@2.74.0': + resolution: {integrity: sha512-9Ypa2eS0Ib/YQClE+BhDSjx7OKjYEF6LAGjTB8X4HucdboGEwR0LZKctNfw6V0PPIAVjjzZxIlNBXGv0ypIkHw==} - '@supabase/realtime-js@2.11.3': - resolution: {integrity: sha512-rMMGtZy2MaSBlNXP5hJZx+ij5JtQGPuBQ7/izE1oKlR1A6SzbN0VWeFTdmDHVa1gcJ72zpQAjbSmByIG6uz/eA==} + '@supabase/realtime-js@2.74.0': + resolution: {integrity: sha512-K5VqpA4/7RO1u1nyD5ICFKzWKu58bIDcPxHY0aFA7MyWkFd0pzi/XYXeoSsAifnD9p72gPIpgxVXCQZKJg1ktQ==} '@supabase/shared-types@0.1.80': resolution: {integrity: sha512-U2ACit34Up5OzB53dthb50YVGcAUzkuWn0Wq9fXWDdfl4Wlp+euWKSSVUMUIQo+bf2phu3V/PmVHEWR6dpls1g==} @@ -8885,13 +8885,13 @@ packages: '@supabase/sql-to-rest@0.1.6': resolution: {integrity: sha512-06KgjeINtc6405XQvfnchBE1azEsU8G2NElfadmvVHKmHa5l2bFzjbtFbpaYgpgTzccHlcDmBaCgedVf2Gyl8Q==} - '@supabase/ssr@0.6.1': - resolution: {integrity: sha512-QtQgEMvaDzr77Mk3vZ3jWg2/y+D8tExYF7vcJT+wQ8ysuvOeGGjYbZlvj5bHYsj/SpC0bihcisnwPrM4Gp5G4g==} + '@supabase/ssr@0.7.0': + resolution: {integrity: sha512-G65t5EhLSJ5c8hTCcXifSL9Q/ZRXvqgXeNo+d3P56f4U1IxwTqjB64UfmfixvmMcjuxnq2yGqEWVJqUcO+AzAg==} peerDependencies: '@supabase/supabase-js': ^2.43.4 - '@supabase/storage-js@2.7.1': - resolution: {integrity: sha512-asYHcyDR1fKqrMpytAS1zjyEfvxuOIp1CIXX7ji4lHHcJKqyk+sLl/Vxgm4sN6u8zvuUtae9e4kDxQP2qrwWBA==} + '@supabase/storage-js@2.74.0': + resolution: {integrity: sha512-o0cTQdMqHh4ERDLtjUp1/KGPbQoNwKRxUh6f8+KQyjC5DSmiw/r+jgFe/WHh067aW+WU8nA9Ytw9ag7OhzxEkQ==} '@supabase/supa-mdx-lint-darwin@0.2.6-alpha': resolution: {integrity: sha512-tDyl2SWfuFb5yckD1cyd5CfmkAbvx9onaxXFrMTP/1bB/sYM3RI2BJQ7/lfZy0jcIiMvc70LroJe5EYx37yYsQ==} @@ -8983,8 +8983,8 @@ packages: resolution: {integrity: sha512-TNbBLSofM6jQg3JwzO4lttd59dScTTzW4p504/OWcgRWghQLRNfxXRJJtdui83gBMLWpgeUZqvgtfYIwS1Flzw==} hasBin: true - '@supabase/supabase-js@2.49.3': - resolution: {integrity: sha512-42imTuAm9VEQGlXT0O6zrSwNnsIblU1eieqrAWj8HSmFaYkxepk/IuUVw1M5hKelk0ZYlqDKNwRErI1rF1EL4w==} + '@supabase/supabase-js@2.74.0': + resolution: {integrity: sha512-IEMM/V6gKdP+N/X31KDIczVzghDpiPWFGLNjS8Rus71KvV6y6ueLrrE/JGCHDrU+9pq5copF3iCa0YQh+9Lq9Q==} '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} @@ -9596,8 +9596,8 @@ packages: '@types/pg@8.15.4': resolution: {integrity: sha512-I6UNVBAoYbvuWkkU3oosC8yxqH21f4/Jc4DK71JLG3dT2mdlGe1z+ep/LQGXaKaOgcvUrsQoPRqfgtMcvZiJhg==} - '@types/phoenix@1.6.4': - resolution: {integrity: sha512-B34A7uot1Cv0XtaHRYDATltAdKx0BvVKNgYNqE4WjtPUa4VQJM7kxeXcVKaH+KS+kCmZ+6w+QaUdcljiheiBJA==} + '@types/phoenix@1.6.6': + resolution: {integrity: sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==} '@types/prismjs@1.26.3': resolution: {integrity: sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==} @@ -9709,6 +9709,9 @@ packages: '@types/wrap-ansi@3.0.0': resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==} + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@types/ws@8.5.10': resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} @@ -28736,11 +28739,11 @@ snapshots: '@stripe/stripe-js@7.5.0': {} - '@supabase/auth-js@2.72.0-rc.11': + '@supabase/auth-js@2.74.0': dependencies: '@supabase/node-fetch': 2.6.15 - '@supabase/functions-js@2.4.4': + '@supabase/functions-js@2.74.0': dependencies: '@supabase/node-fetch': 2.6.15 @@ -28795,21 +28798,15 @@ snapshots: dependencies: '@supabase/node-fetch': 2.6.15 - '@supabase/realtime-js@2.11.2': + '@supabase/postgrest-js@2.74.0': dependencies: '@supabase/node-fetch': 2.6.15 - '@types/phoenix': 1.6.4 - '@types/ws': 8.5.10 - ws: 8.18.3 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - '@supabase/realtime-js@2.11.3': + '@supabase/realtime-js@2.74.0': dependencies: '@supabase/node-fetch': 2.6.15 - '@types/phoenix': 1.6.4 - '@types/ws': 8.5.10 + '@types/phoenix': 1.6.6 + '@types/ws': 8.18.1 ws: 8.18.3 transitivePeerDependencies: - bufferutil @@ -28826,12 +28823,12 @@ snapshots: - encoding - supports-color - '@supabase/ssr@0.6.1(@supabase/supabase-js@2.49.3)': + '@supabase/ssr@0.7.0(@supabase/supabase-js@2.74.0)': dependencies: - '@supabase/supabase-js': 2.49.3 + '@supabase/supabase-js': 2.74.0 cookie: 1.0.2 - '@supabase/storage-js@2.7.1': + '@supabase/storage-js@2.74.0': dependencies: '@supabase/node-fetch': 2.6.15 @@ -28899,14 +28896,14 @@ snapshots: '@supabase/supa-mdx-lint-win32-x64': 0.3.1 node-pty: 1.0.0 - '@supabase/supabase-js@2.49.3': + '@supabase/supabase-js@2.74.0': dependencies: - '@supabase/auth-js': 2.72.0-rc.11 - '@supabase/functions-js': 2.4.4 + '@supabase/auth-js': 2.74.0 + '@supabase/functions-js': 2.74.0 '@supabase/node-fetch': 2.6.15 - '@supabase/postgrest-js': 1.19.2 - '@supabase/realtime-js': 2.11.2 - '@supabase/storage-js': 2.7.1 + '@supabase/postgrest-js': 2.74.0 + '@supabase/realtime-js': 2.74.0 + '@supabase/storage-js': 2.74.0 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -29995,7 +29992,7 @@ snapshots: pg-protocol: 1.10.3 pg-types: 2.2.0 - '@types/phoenix@1.6.4': {} + '@types/phoenix@1.6.6': {} '@types/prismjs@1.26.3': {} @@ -30126,6 +30123,10 @@ snapshots: '@types/wrap-ansi@3.0.0': {} + '@types/ws@8.18.1': + dependencies: + '@types/node': 22.13.14 + '@types/ws@8.5.10': dependencies: '@types/node': 22.13.14 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index ebd7572ae31e5..1329dfd5c7d75 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -5,9 +5,9 @@ packages: - e2e/* catalog: - '@supabase/auth-js': 2.72.0-rc.11 - '@supabase/realtime-js': ^2.11.3 - '@supabase/supabase-js': ^2.47.14 + '@supabase/auth-js': 2.74.0 + '@supabase/realtime-js': 2.74.0 + '@supabase/supabase-js': 2.74.0 '@types/node': ^22.0.0 '@types/react': ^18.3.0 '@types/react-dom': ^18.3.0 From 02d3ba2170a23e40b9f9b5840cda918d00b0d06f Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:52:34 +0200 Subject: [PATCH 03/13] chore: update self-hosted image versions (#37342) * chore: update image versions for docker/docker-compose.yml * chore: update image versions for docker/docker-compose.yml * chore: update image versions for docker/docker-compose.yml * chore: update image versions for docker/docker-compose.yml * chore: update image versions for docker/docker-compose.yml * chore: update image versions for docker/docker-compose.yml * chore: update image versions for docker/docker-compose.yml * chore: update image versions for docker/docker-compose.yml * chore: update image versions for docker/docker-compose.yml * chore: update image versions for docker/docker-compose.yml * chore: revert risky updates --------- Co-authored-by: Han Qiao --- docker/docker-compose.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 6d9192bd5930a..14f7c39f58577 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -11,7 +11,7 @@ services: studio: container_name: supabase-studio - image: supabase/studio:2025.06.30-sha-6f5982d + image: supabase/studio:2025.10.01-sha-8460121 restart: unless-stopped healthcheck: test: @@ -80,7 +80,7 @@ services: auth: container_name: supabase-auth - image: supabase/gotrue:v2.177.0 + image: supabase/gotrue:v2.180.0 restart: unless-stopped healthcheck: test: @@ -163,7 +163,7 @@ services: rest: container_name: supabase-rest - image: postgrest/postgrest:v12.2.12 + image: postgrest/postgrest:v13.0.7 restart: unless-stopped depends_on: db: @@ -187,7 +187,7 @@ services: realtime: # This container name looks inconsistent but is correct because realtime constructs tenant id by parsing the subdomain container_name: realtime-dev.supabase-realtime - image: supabase/realtime:v2.34.47 + image: supabase/realtime:v2.51.11 restart: unless-stopped depends_on: db: @@ -232,7 +232,7 @@ services: # To use S3 backed storage: docker compose -f docker-compose.yml -f docker-compose.s3.yml up storage: container_name: supabase-storage - image: supabase/storage-api:v1.25.7 + image: supabase/storage-api:v1.28.0 restart: unless-stopped volumes: - ./volumes/storage:/var/lib/storage:z @@ -297,7 +297,7 @@ services: meta: container_name: supabase-meta - image: supabase/postgres-meta:v0.91.0 + image: supabase/postgres-meta:v0.91.6 restart: unless-stopped depends_on: db: @@ -340,7 +340,7 @@ services: analytics: container_name: supabase-analytics - image: supabase/logflare:1.14.2 + image: supabase/logflare:1.22.4 restart: unless-stopped ports: - 4000:4000 @@ -389,7 +389,7 @@ services: # Comment out everything below this point if you are using an external Postgres database db: container_name: supabase-db - image: supabase/postgres:15.8.1.060 + image: supabase/postgres:15.8.1.085 restart: unless-stopped volumes: - ./volumes/db/realtime.sql:/docker-entrypoint-initdb.d/migrations/99-realtime.sql:Z @@ -477,7 +477,7 @@ services: # Update the DATABASE_URL if you are using an external Postgres database supavisor: container_name: supabase-pooler - image: supabase/supavisor:2.5.7 + image: supabase/supavisor:2.7.0 restart: unless-stopped ports: - ${POSTGRES_PORT}:5432 From 0ea541938c0d7707458f56ebfbcf0a111a1eee80 Mon Sep 17 00:00:00 2001 From: Alaister Young Date: Wed, 8 Oct 2025 18:43:58 +0800 Subject: [PATCH 04/13] chore: disable account security page (#39319) --- .../layouts/AccountLayout/AccountLayout.tsx | 19 ++++++++++++------ apps/studio/pages/account/security.tsx | 20 +++++++++++++------ .../enabled-features/enabled-features.json | 2 ++ .../enabled-features.schema.json | 6 ++++++ 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/apps/studio/components/layouts/AccountLayout/AccountLayout.tsx b/apps/studio/components/layouts/AccountLayout/AccountLayout.tsx index 679f916b09f61..33b83ecf4faa9 100644 --- a/apps/studio/components/layouts/AccountLayout/AccountLayout.tsx +++ b/apps/studio/components/layouts/AccountLayout/AccountLayout.tsx @@ -4,6 +4,7 @@ import { PropsWithChildren, useEffect } from 'react' import { LOCAL_STORAGE_KEYS } from 'common' import { useCustomContent } from 'hooks/custom-content/useCustomContent' +import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled' import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage' import { withAuth } from 'hooks/misc/withAuth' import { IS_PLATFORM } from 'lib/constants' @@ -19,6 +20,8 @@ const AccountLayout = ({ children, title }: PropsWithChildren { - const { data } = useMfaListFactorsQuery() + const showSecuritySettings = useIsFeatureEnabled('account:show_security_settings') + + const { data } = useMfaListFactorsQuery({ enabled: showSecuritySettings }) + + if (!showSecuritySettings) { + return + } return ( <> diff --git a/packages/common/enabled-features/enabled-features.json b/packages/common/enabled-features/enabled-features.json index e6a8f46bbc041..d47444f59f4b1 100644 --- a/packages/common/enabled-features/enabled-features.json +++ b/packages/common/enabled-features/enabled-features.json @@ -1,6 +1,8 @@ { "$schema": "./enabled-features.schema.json", + "account:show_security_settings": true, + "ai:opt_in_level_disabled": true, "ai:opt_in_level_schema": true, "ai:opt_in_level_schema_and_log": true, diff --git a/packages/common/enabled-features/enabled-features.schema.json b/packages/common/enabled-features/enabled-features.schema.json index 54ba07676190c..96cd9ef0d8e38 100644 --- a/packages/common/enabled-features/enabled-features.schema.json +++ b/packages/common/enabled-features/enabled-features.schema.json @@ -6,6 +6,11 @@ "type": "string" }, + "account:show_security_settings": { + "type": "boolean", + "description": "Show the account security settings page" + }, + "ai:opt_in_level_disabled": { "type": "boolean", "description": "Enable the AI opt in level 'disabled'" @@ -395,6 +400,7 @@ } }, "required": [ + "account:show_security_settings", "ai:opt_in_level_disabled", "ai:opt_in_level_schema", "ai:opt_in_level_schema_and_log", From 8dfa794ab94757df3d1211f867a1eaa9c824efd6 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 8 Oct 2025 07:57:03 -0300 Subject: [PATCH 05/13] docs(swift): update Swift SDK documentation for recent features (#39332) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR updates the Swift SDK documentation to reflect new features from recent merged PRs in supabase-swift: ## Documentation Updates ### PR #812: getClaims method - Added documentation for new `getClaims()` method for JWT verification - Supports both symmetric (HS256) and asymmetric (RS256) JWTs - Includes global JWKS caching with 10-minute TTL - Handles key rotation gracefully - Examples: current session, custom JWT, expired tokens, custom JWKS ### PR #809: OAuth 2.1 client admin endpoints - Added documentation for OAuth 2.1 client administration endpoints - New methods: `listClients()`, `createClient()`, `getClient()`, `deleteClient()`, `regenerateClientSecret()` - All methods under `admin.oauth` namespace requiring `service_role` key - Includes pagination support for listing clients ### PR #806: forceFunctionRegion query parameter - Updated `invoke()` documentation to mention both `x-region` header and `forceFunctionRegion` query parameter - Both are set when a region is specified for better function routing ### PR #805: broadcast replay configuration - Added example for configuring broadcast with replay support - Shows `ReplayOption` with `since` and `limit` parameters - Demonstrates how to detect replayed messages via `meta` field ### PR #795: maxAffected method - Already documented in previous commit (7c29f852c0) - No changes needed ## Files Updated - apps/docs/spec/supabase_swift_v2.yml 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude --- apps/docs/spec/supabase_swift_v2.yml | 227 +++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) diff --git a/apps/docs/spec/supabase_swift_v2.yml b/apps/docs/spec/supabase_swift_v2.yml index ff6477548e808..a3fd138b5eb2f 100644 --- a/apps/docs/spec/supabase_swift_v2.yml +++ b/apps/docs/spec/supabase_swift_v2.yml @@ -1094,6 +1094,67 @@ functions: let session = try await supabase.auth.refreshSession(refreshToken: "custom-refresh-token") ``` + - id: get-claims + title: 'getClaims()' + notes: | + - Verifies a JWT and extracts its claims. + - For symmetric JWTs (HS256), verification is performed server-side via the `getUser()` API. + - For asymmetric JWTs (RS256), verification is performed client-side using Apple Security framework. + - Uses a global JWKS cache shared across all clients with the same storage key for optimal performance. + - Automatically handles key rotation by falling back to server-side verification when a JWK is not found. + - The JWKS cache has a 10-minute TTL (time-to-live). + overwriteParams: + - name: jwt + isOptional: true + type: String + description: > + The JWT to verify. If not provided, uses the access token from the current session. + - name: options + isOptional: true + type: GetClaimsOptions + description: > + Options for JWT verification. Can specify `allowExpired` to skip expiration check and `jwks` to provide custom JSON Web Key Set. + examples: + - id: get-claims-current-session + name: Verify and get claims from current session + isSpotlight: true + code: | + ```swift + let response = try await supabase.auth.getClaims() + print("User ID: \(response.claims.sub ?? "N/A")") + print("Email: \(response.claims.email ?? "N/A")") + print("Role: \(response.claims.role ?? "N/A")") + ``` + - id: get-claims-custom-jwt + name: Verify and get claims from a specific JWT + isSpotlight: false + code: | + ```swift + let customToken = "eyJhbGci..." + let response = try await supabase.auth.getClaims(jwt: customToken) + ``` + - id: get-claims-allow-expired + name: Get claims from an expired JWT + description: Useful for testing or extracting information from expired tokens. + isSpotlight: false + code: | + ```swift + let response = try await supabase.auth.getClaims( + options: GetClaimsOptions(allowExpired: true) + ) + ``` + - id: get-claims-custom-jwks + name: Verify JWT with custom JWKS + description: Provide a custom JSON Web Key Set for verification. + isSpotlight: false + code: | + ```swift + let customJWKS = JWKS(keys: [...]) + let response = try await supabase.auth.getClaims( + options: GetClaimsOptions(jwks: customJWKS) + ) + ``` + - id: start-auto-refresh title: 'startAutoRefresh()' description: | @@ -1395,6 +1456,140 @@ functions: ) ``` + - id: admin-oauth-list-clients + title: 'admin.oauth.listClients()' + description: | + List all OAuth clients with optional pagination. + notes: | + - Requires `service_role` key. + - This method is part of the OAuth 2.1 server administration API. + - Only works when the OAuth 2.1 server is enabled in your Supabase Auth configuration. + overwriteParams: + - name: params + isOptional: true + type: PageParams + description: > + Pagination parameters with `page` and `perPage` options. + examples: + - id: list-oauth-clients + name: List all OAuth clients + isSpotlight: true + code: | + ```swift + let response = try await supabase.auth.admin.oauth.listClients() + ``` + - id: list-oauth-clients-paginated + name: List OAuth clients with pagination + isSpotlight: false + code: | + ```swift + let response = try await supabase.auth.admin.oauth.listClients( + params: PageParams(page: 1, perPage: 10) + ) + ``` + + - id: admin-oauth-create-client + title: 'admin.oauth.createClient()' + description: | + Create a new OAuth client. + notes: | + - Requires `service_role` key. + - This method is part of the OAuth 2.1 server administration API. + - Only works when the OAuth 2.1 server is enabled in your Supabase Auth configuration. + overwriteParams: + - name: params + type: CreateOAuthClientParams + description: > + Parameters for creating the OAuth client including name, redirect URIs, and client type. + examples: + - id: create-oauth-client + name: Create a new OAuth client + isSpotlight: true + code: | + ```swift + let client = try await supabase.auth.admin.oauth.createClient( + params: CreateOAuthClientParams( + name: "My OAuth App", + redirectUris: ["https://example.com/callback"], + clientType: .confidential + ) + ) + ``` + + - id: admin-oauth-get-client + title: 'admin.oauth.getClient()' + description: | + Get details of a specific OAuth client. + notes: | + - Requires `service_role` key. + - This method is part of the OAuth 2.1 server administration API. + overwriteParams: + - name: clientId + type: String + description: > + The UUID of the OAuth client to retrieve. + examples: + - id: get-oauth-client + name: Get OAuth client by ID + isSpotlight: true + code: | + ```swift + let client = try await supabase.auth.admin.oauth.getClient( + clientId: "12345678-1234-1234-1234-123456789012" + ) + ``` + + - id: admin-oauth-delete-client + title: 'admin.oauth.deleteClient()' + description: | + Delete an OAuth client. + notes: | + - Requires `service_role` key. + - This method is part of the OAuth 2.1 server administration API. + - This action cannot be undone. + overwriteParams: + - name: clientId + type: String + description: > + The UUID of the OAuth client to delete. + examples: + - id: delete-oauth-client + name: Delete an OAuth client + isSpotlight: true + code: | + ```swift + try await supabase.auth.admin.oauth.deleteClient( + clientId: "12345678-1234-1234-1234-123456789012" + ) + ``` + + - id: admin-oauth-regenerate-client-secret + title: 'admin.oauth.regenerateClientSecret()' + description: | + Regenerate the secret for an OAuth client. + notes: | + - Requires `service_role` key. + - This method is part of the OAuth 2.1 server administration API. + - The old secret will be immediately invalidated. + - Make sure to update your application with the new secret. + overwriteParams: + - name: clientId + type: String + description: > + The UUID of the OAuth client whose secret should be regenerated. + examples: + - id: regenerate-oauth-client-secret + name: Regenerate OAuth client secret + isSpotlight: true + code: | + ```swift + let client = try await supabase.auth.admin.oauth.regenerateClientSecret( + clientId: "12345678-1234-1234-1234-123456789012" + ) + // The response contains the new secret + print("New secret: \(client.secret ?? "")") + ``` + - id: select title: 'Fetch data: select()' notes: | @@ -4012,6 +4207,7 @@ functions: notes: | - Requires an Authorization header. - When you pass in a body to your function, we automatically attach the Content-Type header for `String`, and `Data`. If it doesn't match any of these types we assume the payload is `json`, serialize it and attach the `Content-Type` header as `application/json`. You can override this behaviour by passing in a `Content-Type` header of your own. + - When a region is specified, both the `x-region` header and `forceFunctionRegion` query parameter are set to ensure proper function routing. examples: - id: invocation-with-decodable name: Invocation with `Decodable` response @@ -4246,6 +4442,37 @@ functions: subscription.cancel() ``` + - id: broadcast-with-replay + name: Configure broadcast with replay + description: | + Replay allows you to receive messages that were broadcast since a specific timestamp. The `meta` field in the message payload will indicate if a message is being replayed. + isSpotlight: false + code: | + ```swift + let config = RealtimeJoinConfig( + broadcast: BroadcastJoinConfig( + acknowledgeBroadcasts: true, + receiveOwnBroadcasts: true, + replay: ReplayOption( + since: 1234567890, + limit: 100 + ) + ) + ) + + let channel = supabase.channel("my-channel", config: config) + + channel.onBroadcast { message in + if let meta = message.payload["meta"] as? [String: Any], + let replayed = meta["replayed"] as? Bool, + replayed { + print("Replayed message: \(meta["id"] ?? "")") + } + } + + await channel.subscribe() + ``` + - id: listen-to-presence-updates name: Listen to presence updates code: | From 82aa70a0756c9bd463c07d6a0ea00d37af412ed0 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Wed, 8 Oct 2025 14:51:55 +0200 Subject: [PATCH 06/13] docs: Add toggle for hiding start menu (#39359) Add toggle for hiding start menu --- .../Navigation/NavigationMenu/NavigationMenu.constants.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts index 53963fb288310..16e9cd7d1f7f5 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts @@ -67,6 +67,7 @@ export const GLOBAL_MENU_ITEMS: GlobalMenuItems = [ icon: 'getting-started', href: '/guides/getting-started', level: 'gettingstarted', + enabled: frameworkQuickstartsEnabled, }, ], [ From 5b2351da8697308bcb9bbfd16a01267b4b943fc7 Mon Sep 17 00:00:00 2001 From: Pamela Chia Date: Wed, 8 Oct 2025 05:58:15 -0700 Subject: [PATCH 07/13] Add tracking for API docs usage (#39307) --- .../interfaces/Auth/Users/UsersV2.tsx | 4 +- .../interfaces/Docs/CodeSnippet.tsx | 23 +++++++++- .../ProjectAPIDocs/Content/Introduction.tsx | 26 ++++++++++++ .../ProjectAPIDocs/ContentSnippet.tsx | 23 +++++++++- .../ProjectAPIDocs/ResourceContent.tsx | 23 +++++++++- apps/studio/components/interfaces/Sidebar.tsx | 40 ++++++++++++++---- .../StorageExplorer/FileExplorerHeader.tsx | 2 +- .../TableGridEditor/GridHeaderActions.tsx | 4 +- .../EdgeFunctionDetailsLayout.tsx | 1 + apps/studio/components/ui/APIDocsButton.tsx | 20 ++++++++- packages/common/telemetry-constants.ts | 42 +++++++++++++++++++ .../SimpleCodeBlock/SimpleCodeBlock.tsx | 3 ++ 12 files changed, 195 insertions(+), 16 deletions(-) diff --git a/apps/studio/components/interfaces/Auth/Users/UsersV2.tsx b/apps/studio/components/interfaces/Auth/Users/UsersV2.tsx index 6570110caf0da..fd4f05d91284c 100644 --- a/apps/studio/components/interfaces/Auth/Users/UsersV2.tsx +++ b/apps/studio/components/interfaces/Auth/Users/UsersV2.tsx @@ -503,7 +503,9 @@ export const UsersV2 = () => {
- {isNewAPIDocsEnabled && } + {isNewAPIDocsEnabled && ( + + )} @@ -285,7 +285,9 @@ export const RestoreToNewProject = () => { being created. You'll be able to restore again once the project is ready.

From 08fa5641b9c44922bb3d42e0079669fa6c916cd2 Mon Sep 17 00:00:00 2001 From: Steven Eubank <47563310+smeubank@users.noreply.github.com> Date: Wed, 8 Oct 2025 16:02:18 +0100 Subject: [PATCH 10/13] fix(onboarding)add-me-to-supabase (#39298) onboarding --- apps/docs/public/humans.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/docs/public/humans.txt b/apps/docs/public/humans.txt index efd334c142906..31a40d758f11b 100644 --- a/apps/docs/public/humans.txt +++ b/apps/docs/public/humans.txt @@ -129,6 +129,7 @@ Sreyas Udayavarman Stanislav M Stephen Morgan Steve Chavez +Steven Eubank Stojan Dimitrovski Sugu Sougoumarane Supun Sudaraka Kalidasa From 411b53227b43c780ec2cfbae4488a986d543088c Mon Sep 17 00:00:00 2001 From: Monica Khoury <99693443+monicakh@users.noreply.github.com> Date: Wed, 8 Oct 2025 18:03:49 +0300 Subject: [PATCH 11/13] Docs: fix incorrect link in sessions guide (#39268) --- apps/docs/content/guides/auth/sessions.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/content/guides/auth/sessions.mdx b/apps/docs/content/guides/auth/sessions.mdx index ebaeec2937cc2..1b79d9f8d6644 100644 --- a/apps/docs/content/guides/auth/sessions.mdx +++ b/apps/docs/content/guides/auth/sessions.mdx @@ -69,7 +69,7 @@ Otherwise sessions are progressively deleted from the database 24 hours after th ### What are recommended values for access token (JWT) expiration? -Most applications should use the default expiration time of 1 hour. This can be customized in your project's [Auth settings](/dashboard/project/_/auth/sessions) in the Advanced Settings section. +Most applications should use the default expiration time of 1 hour. This can be customized in your project's [Auth settings](/dashboard/project/_/settings/jwt) in the Advanced Settings section. Setting a value over 1 hour is generally discouraged for security reasons, but it may make sense in certain situations. From 8ceee596fa5f35ba7f8d0c26b09a3db483c2653e Mon Sep 17 00:00:00 2001 From: hannah-bowers Date: Wed, 8 Oct 2025 08:06:37 -0700 Subject: [PATCH 12/13] Hannah - adding name to humans.txt (#39337) --- apps/docs/public/humans.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/docs/public/humans.txt b/apps/docs/public/humans.txt index 31a40d758f11b..2436fa2207d68 100644 --- a/apps/docs/public/humans.txt +++ b/apps/docs/public/humans.txt @@ -60,6 +60,7 @@ Greg Kress Greg P Greg Richardson Guilherme Souza +Hannah Bowers Hardik Maheshwari Haydn Maley Hieu Pham From ff898adb7fc0fab72c5b9f9fff10086ed40c8b58 Mon Sep 17 00:00:00 2001 From: Nick Littman Date: Wed, 8 Oct 2025 11:10:31 -0400 Subject: [PATCH 13/13] adding myself to humans.txt (#38563) --- apps/docs/public/humans.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/docs/public/humans.txt b/apps/docs/public/humans.txt index 2436fa2207d68..8226944743a8d 100644 --- a/apps/docs/public/humans.txt +++ b/apps/docs/public/humans.txt @@ -103,6 +103,7 @@ Matt Johnston Matt Rossman Monica Khoury Mykhailo Mischa Lieibenson +Nick Littman Nyannyacha Oli R Pamela Chia