From 7b941a0fd7f38690557385640d8aecd27678272e Mon Sep 17 00:00:00 2001 From: Saxon Fletcher Date: Tue, 12 Aug 2025 20:18:24 +1000 Subject: [PATCH 1/7] Attempt to fix completion (#37787) * attempt to fix completion * use experimental output --- .../interfaces/SQLEditor/SQLEditor.tsx | 108 ++++++++++-------- apps/studio/components/ui/AIEditor/index.tsx | 79 ++++++++----- apps/studio/pages/api/ai/code/complete.ts | 12 +- 3 files changed, 123 insertions(+), 76 deletions(-) diff --git a/apps/studio/components/interfaces/SQLEditor/SQLEditor.tsx b/apps/studio/components/interfaces/SQLEditor/SQLEditor.tsx index 9f3f8e0c174b2..1238397807383 100644 --- a/apps/studio/components/interfaces/SQLEditor/SQLEditor.tsx +++ b/apps/studio/components/interfaces/SQLEditor/SQLEditor.tsx @@ -1,4 +1,3 @@ -import { useCompletion } from '@ai-sdk/react' import type { Monaco } from '@monaco-editor/react' import { useQueryClient } from '@tanstack/react-query' import { ChevronUp, Loader2 } from 'lucide-react' @@ -453,22 +452,70 @@ export const SQLEditor = () => { closeDiff() }, [closeDiff, resetPrompt, sendEvent]) - const { - complete, - completion, - isLoading: isCompletionLoading, - } = useCompletion({ - api: `${BASE_PATH}/api/ai/code/complete`, - body: { - projectRef: project?.ref, - connectionString: project?.connectionString, - language: 'sql', - orgSlug: org?.slug, - }, - onError: (error) => { - toast.error(`Failed to generate SQL: ${error.message}`) + const [isCompletionLoading, setIsCompletionLoading] = useState(false) + + const complete = useCallback( + async ( + prompt: string, + options?: { + headers?: Record + body?: { completionMetadata?: any } + } + ) => { + try { + setIsCompletionLoading(true) + + const response = await fetch(`${BASE_PATH}/api/ai/code/complete`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...(options?.headers ?? {}), + }, + body: JSON.stringify({ + projectRef: project?.ref, + connectionString: project?.connectionString, + language: 'sql', + orgSlug: org?.slug, + ...(options?.body ?? {}), + }), + }) + + if (!response.ok) { + const errorText = await response.text() + throw new Error(errorText || 'Failed to generate completion') + } + + // API returns a JSON-encoded string + const text: string = await response.json() + + const meta = options?.body?.completionMetadata ?? {} + const beforeSelection: string = meta.textBeforeCursor ?? '' + const afterSelection: string = meta.textAfterCursor ?? '' + const selection: string = meta.selection ?? '' + + const original = beforeSelection + selection + afterSelection + const modified = beforeSelection + text + afterSelection + + const formattedModified = formatSql(modified) + setSourceSqlDiff({ original, modified: formattedModified }) + setSelectedDiffType(DiffType.Modification) + setPromptState((prev) => ({ ...prev, isLoading: false })) + setIsCompletionLoading(false) + } catch (error: any) { + toast.error(`Failed to generate SQL: ${error?.message ?? 'Unknown error'}`) + setIsCompletionLoading(false) + throw error + } }, - }) + [ + org?.slug, + project?.connectionString, + project?.ref, + setPromptState, + setSelectedDiffType, + setSourceSqlDiff, + ] + ) const handlePrompt = async ( prompt: string, @@ -593,35 +640,6 @@ export const SQLEditor = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [snapV2.diffContent]) - useEffect(() => { - if (!completion) { - return - } - - const original = - promptState.beforeSelection + promptState.selection + promptState.afterSelection - const modified = promptState.beforeSelection + completion + promptState.afterSelection - - if (isCompletionLoading) { - // Attempt to format the modified SQL in case the LLM left out indentation, etc - let formattedModified = formatSql(modified) - - setSourceSqlDiff({ - original, - modified: formattedModified, - }) - setSelectedDiffType(DiffType.Modification) - setPromptState((prev) => ({ ...prev, isLoading: false })) - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ - completion, - promptState.beforeSelection, - promptState.selection, - promptState.afterSelection, - isCompletionLoading, - ]) - // We want to check if the diff editor is mounted and if it is, we want to show the widget // We also want to cleanup the widget when the diff editor is closed useEffect(() => { diff --git a/apps/studio/components/ui/AIEditor/index.tsx b/apps/studio/components/ui/AIEditor/index.tsx index eb34c04b1801f..b27d47061e28d 100644 --- a/apps/studio/components/ui/AIEditor/index.tsx +++ b/apps/studio/components/ui/AIEditor/index.tsx @@ -1,5 +1,4 @@ import Editor, { DiffEditor, Monaco, OnMount } from '@monaco-editor/react' -import { useCompletion } from '@ai-sdk/react' import { AnimatePresence, motion } from 'framer-motion' import { Command } from 'lucide-react' import { editor as monacoEditor } from 'monaco-editor' @@ -71,26 +70,64 @@ const AIEditor = ({ }) const [promptInput, setPromptInput] = useState(initialPrompt || '') - const { - complete, - completion, - isLoading: isCompletionLoading, - setCompletion, - } = useCompletion({ - api: aiEndpoint || '', - body: aiMetadata, - onError: (error) => { - toast.error(`Failed to generate: ${error.message}`) + const [isCompletionLoading, setIsCompletionLoading] = useState(false) + + const complete = useCallback( + async ( + prompt: string, + options?: { + headers?: Record + body?: { completionMetadata?: any } + } + ) => { + try { + if (!aiEndpoint) throw new Error('AI endpoint is not configured') + setIsCompletionLoading(true) + + const response = await fetch(aiEndpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...(options?.headers ?? {}), + }, + body: JSON.stringify({ + ...(aiMetadata ?? {}), + ...(options?.body ?? {}), + }), + }) + + if (!response.ok) { + const errorText = await response.text() + throw new Error(errorText || 'Failed to generate completion') + } + + const text: string = await response.json() + + const meta = options?.body?.completionMetadata ?? {} + const beforeSelection: string = meta.textBeforeCursor ?? '' + const afterSelection: string = meta.textAfterCursor ?? '' + const selection: string = meta.selection ?? '' + + const original = beforeSelection + selection + afterSelection + const modified = beforeSelection + text + afterSelection + + setDiffValue({ original, modified }) + setIsDiffMode(true) + } catch (error: any) { + toast.error(`Failed to generate: ${error?.message ?? 'Unknown error'}`) + } finally { + setIsCompletionLoading(false) + } }, - }) + [aiEndpoint, aiMetadata] + ) const handleReset = useCallback(() => { - setCompletion('') setIsDiffMode(false) setPromptState((prev) => ({ ...prev, isOpen: false })) setPromptInput('') editorRef.current?.focus() - }, [setCompletion]) + }, []) const handleAcceptDiff = useCallback(() => { if (diffValue.modified) { @@ -269,20 +306,6 @@ const AIEditor = ({ } }, [isDiffMode]) - useEffect(() => { - if (!completion) { - setIsDiffMode(false) - return - } - - const original = - promptState.beforeSelection + promptState.selection + promptState.afterSelection - const modified = promptState.beforeSelection + completion + promptState.afterSelection - - setDiffValue({ original, modified }) - setIsDiffMode(true) - }, [completion, promptState.beforeSelection, promptState.selection, promptState.afterSelection]) - useEffect(() => { const handleKeyboard = (event: KeyboardEvent) => { if (event.key === 'Escape') { diff --git a/apps/studio/pages/api/ai/code/complete.ts b/apps/studio/pages/api/ai/code/complete.ts index 157989ffdf5e0..13957ee1511b0 100644 --- a/apps/studio/pages/api/ai/code/complete.ts +++ b/apps/studio/pages/api/ai/code/complete.ts @@ -1,5 +1,5 @@ import pgMeta from '@supabase/pg-meta' -import { ModelMessage, stepCountIs, streamText } from 'ai' +import { ModelMessage, stepCountIs, generateText, Output } from 'ai' import { IS_PLATFORM } from 'common' import { source } from 'common-tags' import { executeSql } from 'data/sql/execute-sql-query' @@ -18,6 +18,7 @@ import { getTools } from 'lib/ai/tools' import apiWrapper from 'lib/api/apiWrapper' import { queryPgMetaSelfHosted } from 'lib/self-hosted' import { NextApiRequest, NextApiResponse } from 'next' +import { z } from 'zod/v4' export const maxDuration = 60 @@ -148,14 +149,19 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { accessToken, }) - const result = streamText({ + const { experimental_output } = await generateText({ model, stopWhen: stepCountIs(5), + experimental_output: Output.object({ + schema: z.object({ + code: z.string().describe('The modified code'), + }), + }), messages: coreMessages, tools, }) - return result.pipeUIMessageStreamToResponse(res) + return res.status(200).json(experimental_output?.code) } catch (error) { console.error('Completion error:', error) return res.status(500).json({ From e320368dc7bd3026f5b4e14762b3c8d6f4b61b19 Mon Sep 17 00:00:00 2001 From: Joshen Lim Date: Tue, 12 Aug 2025 17:34:53 +0700 Subject: [PATCH 2/7] Part 2 of swapping useCheckPermissions with useAsyncCheckProjectPermissions (#37860) * Part 2 of swapping useCheckPermissions with useAsyncCheckProjectPermissions * Fix TS * Address feedback * Fix --- .../BranchManagement/CreateBranchModal.tsx | 7 +- .../interfaces/BranchManagement/Overview.tsx | 17 ++- .../components/interfaces/Connect/Connect.tsx | 7 +- .../Database/Backups/BackupItem.tsx | 11 +- .../Database/Backups/BackupsEmpty.tsx | 4 +- .../Database/Backups/BackupsList.tsx | 6 +- .../Database/Backups/BackupsStorageAlert.tsx | 7 +- .../Database/Backups/PITR/PITRNotice.tsx | 4 +- .../Database/Backups/PITR/PITRSelection.tsx | 4 +- .../Database/Backups/PITR/PITRStatus.tsx | 6 +- .../RestoreToNewProject/BackupsList.tsx | 2 +- .../Database/Extensions/ExtensionCard.tsx | 4 +- .../Database/Extensions/Extensions.tsx | 9 +- .../Functions/FunctionsList/FunctionList.tsx | 4 +- .../Functions/FunctionsList/FunctionsList.tsx | 11 +- .../Database/Hooks/HooksList/HookList.tsx | 25 ++-- .../Database/Hooks/HooksList/HooksList.tsx | 27 +++-- .../Hooks/HooksList/HooksListEmpty.tsx | 4 +- .../Database/Hooks/HooksList/SchemaTable.tsx | 11 +- .../Publications/PublicationsList.tsx | 17 +-- .../Publications/PublicationsTableItem.tsx | 8 +- .../Publications/PublicationsTables.tsx | 35 +++--- .../Database/Roles/CreateRolePanel.tsx | 4 +- .../Database/Roles/DeleteRoleModal.tsx | 4 +- .../interfaces/Database/Roles/RoleRow.tsx | 4 +- .../Database/Roles/RoleRowSkeleton.tsx | 4 +- .../interfaces/Database/Roles/RolesList.tsx | 15 ++- .../interfaces/Database/Tables/ColumnList.tsx | 16 +-- .../interfaces/Database/Tables/TableList.tsx | 111 +++++++++--------- .../Triggers/TriggersList/TriggerList.tsx | 7 +- .../Triggers/TriggersList/TriggersList.tsx | 9 +- .../components/interfaces/Database/index.ts | 6 - .../Integrations/Webhooks/ListTab.tsx | 15 ++- .../interfaces/Realtime/Inspector/Header.tsx | 16 ++- .../Realtime/Inspector/MessagesTable.tsx | 15 ++- .../interfaces/Realtime/Inspector/index.tsx | 2 +- apps/studio/components/ui/SchemaSelector.tsx | 7 +- .../database-triggers-query.ts | 2 +- .../pages/project/[ref]/branches/index.tsx | 19 ++- .../project/[ref]/branches/merge-requests.tsx | 9 +- .../project/[ref]/database/backups/pitr.tsx | 6 +- .../backups/restore-to-new-project.tsx | 9 +- .../[ref]/database/backups/scheduled.tsx | 6 +- .../project/[ref]/database/extensions.tsx | 9 +- .../project/[ref]/database/functions.tsx | 8 +- .../project/[ref]/database/publications.tsx | 12 +- .../project/[ref]/database/tables/[id].tsx | 2 +- .../project/[ref]/database/tables/index.tsx | 4 +- .../pages/project/[ref]/database/triggers.tsx | 8 +- .../[ref]/functions/[functionSlug]/code.tsx | 8 +- .../project/[ref]/realtime/inspector.tsx | 11 +- .../pages/project/[ref]/reports/database.tsx | 30 ++--- .../pages/project/[ref]/reports/index.tsx | 16 ++- .../[ref]/settings/jwt/signing-keys.tsx | 9 +- .../project/[ref]/settings/log-drains.tsx | 24 ++-- 55 files changed, 352 insertions(+), 305 deletions(-) diff --git a/apps/studio/components/interfaces/BranchManagement/CreateBranchModal.tsx b/apps/studio/components/interfaces/BranchManagement/CreateBranchModal.tsx index f814b5f291f85..2a774632f1863 100644 --- a/apps/studio/components/interfaces/BranchManagement/CreateBranchModal.tsx +++ b/apps/studio/components/interfaces/BranchManagement/CreateBranchModal.tsx @@ -24,7 +24,7 @@ import { useGitHubConnectionsQuery } from 'data/integrations/github-connections- import { projectKeys } from 'data/projects/keys' import { useProjectAddonsQuery } from 'data/subscriptions/project-addons-query' import { useSendEventMutation } from 'data/telemetry/send-event-mutation' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { useFlag } from 'hooks/ui/useFlag' @@ -114,7 +114,10 @@ export const CreateBranchModal = () => { }, }) - const canCreateBranch = useCheckPermissions(PermissionAction.CREATE, 'preview_branches') + const { can: canCreateBranch } = useAsyncCheckProjectPermissions( + PermissionAction.CREATE, + 'preview_branches' + ) const githubConnection = connections?.find((connection) => connection.project.ref === projectRef) diff --git a/apps/studio/components/interfaces/BranchManagement/Overview.tsx b/apps/studio/components/interfaces/BranchManagement/Overview.tsx index eebf5b7963144..88257f88afda3 100644 --- a/apps/studio/components/interfaces/BranchManagement/Overview.tsx +++ b/apps/studio/components/interfaces/BranchManagement/Overview.tsx @@ -23,7 +23,7 @@ import { useBranchResetMutation } from 'data/branches/branch-reset-mutation' import { useBranchUpdateMutation } from 'data/branches/branch-update-mutation' import type { Branch } from 'data/branches/branches-query' import { branchKeys } from 'data/branches/keys' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { Button, DropdownMenu, @@ -169,8 +169,14 @@ const PreviewBranchActions = ({ const queryClient = useQueryClient() const projectRef = branch.parent_project_ref ?? branch.project_ref - const canDeleteBranches = useCheckPermissions(PermissionAction.DELETE, 'preview_branches') - const canUpdateBranches = useCheckPermissions(PermissionAction.UPDATE, 'preview_branches') + const { can: canDeleteBranches } = useAsyncCheckProjectPermissions( + PermissionAction.DELETE, + 'preview_branches' + ) + const { can: canUpdateBranches } = useAsyncCheckProjectPermissions( + PermissionAction.UPDATE, + 'preview_branches' + ) const { data } = useBranchQuery({ projectRef, id: branch.id }) const isBranchActiveHealthy = data?.status === 'ACTIVE_HEALTHY' @@ -381,7 +387,10 @@ const PreviewBranchActions = ({ // Actions for main (production) branch const MainBranchActions = ({ branch, repo }: { branch: Branch; repo: string }) => { const { ref: projectRef } = useParams() - const canUpdateBranches = useCheckPermissions(PermissionAction.UPDATE, 'preview_branches') + const { can: canUpdateBranches } = useAsyncCheckProjectPermissions( + PermissionAction.UPDATE, + 'preview_branches' + ) const [showEditBranchModal, setShowEditBranchModal] = useState(false) return ( diff --git a/apps/studio/components/interfaces/Connect/Connect.tsx b/apps/studio/components/interfaces/Connect/Connect.tsx index 03482aeee43a7..6d3065c670a87 100644 --- a/apps/studio/components/interfaces/Connect/Connect.tsx +++ b/apps/studio/components/interfaces/Connect/Connect.tsx @@ -9,7 +9,7 @@ import { ButtonTooltip } from 'components/ui/ButtonTooltip' import Panel from 'components/ui/Panel' import { getKeys, useAPIKeysQuery } from 'data/api-keys/api-keys-query' import { useProjectSettingsV2Query } from 'data/config/project-settings-v2-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { PROJECT_STATUS } from 'lib/constants' import { @@ -55,7 +55,10 @@ export const Connect = () => { ) const { data: settings } = useProjectSettingsV2Query({ projectRef }, { enabled: showConnect }) - const canReadAPIKeys = useCheckPermissions(PermissionAction.READ, 'service_api_keys') + const { can: canReadAPIKeys } = useAsyncCheckProjectPermissions( + PermissionAction.READ, + 'service_api_keys' + ) const handleParentChange = (value: string) => { setSelectedParent(value) diff --git a/apps/studio/components/interfaces/Database/Backups/BackupItem.tsx b/apps/studio/components/interfaces/Database/Backups/BackupItem.tsx index 7b9de9b086388..dbe0a9ca5e440 100644 --- a/apps/studio/components/interfaces/Database/Backups/BackupItem.tsx +++ b/apps/studio/components/interfaces/Database/Backups/BackupItem.tsx @@ -6,7 +6,7 @@ import { ButtonTooltip } from 'components/ui/ButtonTooltip' import { InlineLink } from 'components/ui/InlineLink' import { useBackupDownloadMutation } from 'data/database/backup-download-mutation' import type { DatabaseBackup } from 'data/database/backups-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { Badge, Tooltip, TooltipContent, TooltipTrigger } from 'ui' import { TimestampInfo } from 'ui-patterns' @@ -17,9 +17,9 @@ interface BackupItemProps { onSelectBackup: () => void } -const BackupItem = ({ index, isHealthy, backup, onSelectBackup }: BackupItemProps) => { +export const BackupItem = ({ index, isHealthy, backup, onSelectBackup }: BackupItemProps) => { const { ref: projectRef } = useParams() - const canTriggerScheduledBackups = useCheckPermissions( + const { can: canTriggerScheduledBackups } = useAsyncCheckProjectPermissions( PermissionAction.INFRA_EXECUTE, 'queue_job.restore.prepare' ) @@ -38,8 +38,7 @@ const BackupItem = ({ index, isHealthy, backup, onSelectBackup }: BackupItemProp }) const generateSideButtons = (backup: DatabaseBackup) => { - // [Joshen] API typing is incorrect here, status is getting typed as Record - if ((backup as any).status === 'COMPLETED') + if (backup.status === 'COMPLETED') return (
) } - -export default BackupItem diff --git a/apps/studio/components/interfaces/Database/Backups/BackupsEmpty.tsx b/apps/studio/components/interfaces/Database/Backups/BackupsEmpty.tsx index d0d83a822eaa5..fd00454dadf8f 100644 --- a/apps/studio/components/interfaces/Database/Backups/BackupsEmpty.tsx +++ b/apps/studio/components/interfaces/Database/Backups/BackupsEmpty.tsx @@ -1,6 +1,6 @@ import { Info } from 'lucide-react' -const BackupsEmpty = () => { +export const BackupsEmpty = () => { return (
@@ -10,5 +10,3 @@ const BackupsEmpty = () => {
) } - -export default BackupsEmpty diff --git a/apps/studio/components/interfaces/Database/Backups/BackupsList.tsx b/apps/studio/components/interfaces/Database/Backups/BackupsList.tsx index 484bfe785eca6..7e131ff9992c2 100644 --- a/apps/studio/components/interfaces/Database/Backups/BackupsList.tsx +++ b/apps/studio/components/interfaces/Database/Backups/BackupsList.tsx @@ -14,9 +14,9 @@ import { setProjectStatus } from 'data/projects/projects-query' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { PROJECT_STATUS } from 'lib/constants' import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' -import BackupItem from './BackupItem' -import BackupsEmpty from './BackupsEmpty' -import BackupsStorageAlert from './BackupsStorageAlert' +import { BackupItem } from './BackupItem' +import { BackupsEmpty } from './BackupsEmpty' +import { BackupsStorageAlert } from './BackupsStorageAlert' const BackupsList = () => { const router = useRouter() diff --git a/apps/studio/components/interfaces/Database/Backups/BackupsStorageAlert.tsx b/apps/studio/components/interfaces/Database/Backups/BackupsStorageAlert.tsx index e1544e143935a..52e0c0184e31e 100644 --- a/apps/studio/components/interfaces/Database/Backups/BackupsStorageAlert.tsx +++ b/apps/studio/components/interfaces/Database/Backups/BackupsStorageAlert.tsx @@ -1,7 +1,6 @@ -import { AlertDescription_Shadcn_, Alert_Shadcn_ } from 'ui' -import { WarningIcon } from 'ui' +import { AlertDescription_Shadcn_, Alert_Shadcn_, WarningIcon } from 'ui' -const BackupsStorageAlert = () => { +export const BackupsStorageAlert = () => { return ( @@ -13,5 +12,3 @@ const BackupsStorageAlert = () => { ) } - -export default BackupsStorageAlert diff --git a/apps/studio/components/interfaces/Database/Backups/PITR/PITRNotice.tsx b/apps/studio/components/interfaces/Database/Backups/PITR/PITRNotice.tsx index 7e6f70b3f3fa2..33a4d11e0b816 100644 --- a/apps/studio/components/interfaces/Database/Backups/PITR/PITRNotice.tsx +++ b/apps/studio/components/interfaces/Database/Backups/PITR/PITRNotice.tsx @@ -6,7 +6,7 @@ import { useParams } from 'common' import { ButtonTooltip } from 'components/ui/ButtonTooltip' import { FormPanel } from 'components/ui/Forms/FormPanel' import { useProjectAddonsQuery } from 'data/subscriptions/project-addons-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { getPITRRetentionDuration } from './PITR.utils' const PITRNotice = ({}) => { @@ -14,7 +14,7 @@ const PITRNotice = ({}) => { const { data: addonsResponse } = useProjectAddonsQuery({ projectRef }) const retentionPeriod = getPITRRetentionDuration(addonsResponse?.selected_addons ?? []) - const canUpdateSubscription = useCheckPermissions( + const { can: canUpdateSubscription } = useAsyncCheckProjectPermissions( PermissionAction.BILLING_WRITE, 'stripe.subscriptions' ) diff --git a/apps/studio/components/interfaces/Database/Backups/PITR/PITRSelection.tsx b/apps/studio/components/interfaces/Database/Backups/PITR/PITRSelection.tsx index 86a651a0da516..fa2819c877f57 100644 --- a/apps/studio/components/interfaces/Database/Backups/PITR/PITRSelection.tsx +++ b/apps/studio/components/interfaces/Database/Backups/PITR/PITRSelection.tsx @@ -18,8 +18,8 @@ import { Modal, WarningIcon, } from 'ui' -import BackupsEmpty from '../BackupsEmpty' -import BackupsStorageAlert from '../BackupsStorageAlert' +import { BackupsEmpty } from '../BackupsEmpty' +import { BackupsStorageAlert } from '../BackupsStorageAlert' import type { Timezone } from './PITR.types' import { getClientTimezone } from './PITR.utils' import PITRStatus from './PITRStatus' diff --git a/apps/studio/components/interfaces/Database/Backups/PITR/PITRStatus.tsx b/apps/studio/components/interfaces/Database/Backups/PITR/PITRStatus.tsx index 128a84e006e28..0f77410269344 100644 --- a/apps/studio/components/interfaces/Database/Backups/PITR/PITRStatus.tsx +++ b/apps/studio/components/interfaces/Database/Backups/PITR/PITRStatus.tsx @@ -3,13 +3,13 @@ import { useParams } from 'common' import dayjs from 'dayjs' import { AlertCircle } from 'lucide-react' +import { ButtonTooltip } from 'components/ui/ButtonTooltip' import { FormPanel } from 'components/ui/Forms/FormPanel' import { useBackupsQuery } from 'data/database/backups-query' import { useReadReplicasQuery } from 'data/read-replicas/replicas-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import type { Timezone } from './PITR.types' import { TimezoneSelection } from './TimezoneSelection' -import { ButtonTooltip } from 'components/ui/ButtonTooltip' interface PITRStatusProps { selectedTimezone: Timezone @@ -41,7 +41,7 @@ const PITRStatus = ({ .tz(selectedTimezone?.utc[0]) .format('DD MMM YYYY, HH:mm:ss') - const canTriggerPhysicalBackup = useCheckPermissions( + const { can: canTriggerPhysicalBackup } = useAsyncCheckProjectPermissions( PermissionAction.INFRA_EXECUTE, 'queue_job.walg.prepare_restore' ) diff --git a/apps/studio/components/interfaces/Database/Backups/RestoreToNewProject/BackupsList.tsx b/apps/studio/components/interfaces/Database/Backups/RestoreToNewProject/BackupsList.tsx index e25d3fad34096..c7868594841b5 100644 --- a/apps/studio/components/interfaces/Database/Backups/RestoreToNewProject/BackupsList.tsx +++ b/apps/studio/components/interfaces/Database/Backups/RestoreToNewProject/BackupsList.tsx @@ -4,7 +4,7 @@ import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { Badge, Button } from 'ui' import { TimestampInfo } from 'ui-patterns' -import BackupsEmpty from '../BackupsEmpty' +import { BackupsEmpty } from '../BackupsEmpty' interface BackupsListProps { onSelectRestore: (id: number) => void diff --git a/apps/studio/components/interfaces/Database/Extensions/ExtensionCard.tsx b/apps/studio/components/interfaces/Database/Extensions/ExtensionCard.tsx index 68d280a02689a..9e1e2c38af001 100644 --- a/apps/studio/components/interfaces/Database/Extensions/ExtensionCard.tsx +++ b/apps/studio/components/interfaces/Database/Extensions/ExtensionCard.tsx @@ -7,7 +7,7 @@ import { toast } from 'sonner' import { ButtonTooltip } from 'components/ui/ButtonTooltip' import { useDatabaseExtensionDisableMutation } from 'data/database-extensions/database-extension-disable-mutation' import { DatabaseExtension } from 'data/database-extensions/database-extensions-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useIsOrioleDb, useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { extensions } from 'shared-data' import { Button, cn, Switch, Tooltip, TooltipContent, TooltipTrigger } from 'ui' @@ -28,7 +28,7 @@ const ExtensionCard = ({ extension }: ExtensionCardProps) => { const [isDisableModalOpen, setIsDisableModalOpen] = useState(false) const [showConfirmEnableModal, setShowConfirmEnableModal] = useState(false) - const canUpdateExtensions = useCheckPermissions( + const { can: canUpdateExtensions } = useAsyncCheckProjectPermissions( PermissionAction.TENANT_SQL_ADMIN_WRITE, 'extensions' ) diff --git a/apps/studio/components/interfaces/Database/Extensions/Extensions.tsx b/apps/studio/components/interfaces/Database/Extensions/Extensions.tsx index 73ca129d0c5db..b9e629dcda1c5 100644 --- a/apps/studio/components/interfaces/Database/Extensions/Extensions.tsx +++ b/apps/studio/components/interfaces/Database/Extensions/Extensions.tsx @@ -9,7 +9,7 @@ import InformationBox from 'components/ui/InformationBox' import NoSearchResults from 'components/ui/NoSearchResults' import ShimmeringLoader from 'components/ui/ShimmeringLoader' import { useDatabaseExtensionsQuery } from 'data/database-extensions/database-extensions-query' -import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { Input } from 'ui' import ExtensionCard from './ExtensionCard' @@ -42,11 +42,8 @@ const Extensions = () => { (ext) => !isNull(ext.installed_version) ) - const canUpdateExtensions = useCheckPermissions( - PermissionAction.TENANT_SQL_ADMIN_WRITE, - 'extensions' - ) - const isPermissionsLoaded = usePermissionsLoaded() + const { can: canUpdateExtensions, isSuccess: isPermissionsLoaded } = + useAsyncCheckProjectPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'extensions') useEffect(() => { if (filter !== undefined) setFilterString(filter as string) diff --git a/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionList.tsx b/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionList.tsx index 9e42241f27cd2..4d72806bd16a7 100644 --- a/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionList.tsx +++ b/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionList.tsx @@ -6,7 +6,7 @@ import { useRouter } from 'next/router' import Table from 'components/to-be-cleaned/Table' import { ButtonTooltip } from 'components/ui/ButtonTooltip' import { useDatabaseFunctionsQuery } from 'data/database-functions/database-functions-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { useAiAssistantStateSnapshot } from 'state/ai-assistant-state' import { @@ -50,7 +50,7 @@ const FunctionList = ({ (func) => func.name.toLocaleLowerCase() ) const projectRef = selectedProject?.ref - const canUpdateFunctions = useCheckPermissions( + const { can: canUpdateFunctions } = useAsyncCheckProjectPermissions( PermissionAction.TENANT_SQL_ADMIN_WRITE, 'functions' ) diff --git a/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionsList.tsx b/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionsList.tsx index 0af82c75f81d7..9f47830498920 100644 --- a/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionsList.tsx +++ b/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionsList.tsx @@ -13,7 +13,7 @@ import SchemaSelector from 'components/ui/SchemaSelector' import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader' import { useDatabaseFunctionsQuery } from 'data/database-functions/database-functions-query' import { useSchemasQuery } from 'data/database/schemas-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useQuerySchemaState } from 'hooks/misc/useSchemaQueryState' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { useIsProtectedSchema } from 'hooks/useProtectedSchemas' @@ -51,18 +51,19 @@ const FunctionsList = ({ router.push(url) } - const canCreateFunctions = useCheckPermissions( + const { can: canCreateFunctions } = useAsyncCheckProjectPermissions( PermissionAction.TENANT_SQL_ADMIN_WRITE, 'functions' ) - const { data: schemas } = useSchemasQuery({ + const { isSchemaLocked } = useIsProtectedSchema({ schema: selectedSchema }) + + // [Joshen] This is to preload the data for the Schema Selector + useSchemasQuery({ projectRef: project?.ref, connectionString: project?.connectionString, }) - const { isSchemaLocked } = useIsProtectedSchema({ schema: selectedSchema }) - const { data: functions, error, diff --git a/apps/studio/components/interfaces/Database/Hooks/HooksList/HookList.tsx b/apps/studio/components/interfaces/Database/Hooks/HooksList/HookList.tsx index 4f37d899979c2..c259acb39d0c5 100644 --- a/apps/studio/components/interfaces/Database/Hooks/HooksList/HookList.tsx +++ b/apps/studio/components/interfaces/Database/Hooks/HooksList/HookList.tsx @@ -1,3 +1,4 @@ +import { PostgresTrigger } from '@supabase/postgres-meta' import { PermissionAction } from '@supabase/shared-types/out/constants' import { includes, noop } from 'lodash' import { Edit3, MoreVertical, Trash } from 'lucide-react' @@ -7,7 +8,7 @@ import { useParams } from 'common' import Table from 'components/to-be-cleaned/Table' import { ButtonTooltip } from 'components/ui/ButtonTooltip' import { useDatabaseHooksQuery } from 'data/database-triggers/database-triggers-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { BASE_PATH } from 'lib/constants' import { @@ -23,11 +24,16 @@ import { export interface HookListProps { schema: string filterString: string - editHook: (hook: any) => void - deleteHook: (hook: any) => void + editHook: (hook: PostgresTrigger) => void + deleteHook: (hook: PostgresTrigger) => void } -const HookList = ({ schema, filterString, editHook = noop, deleteHook = noop }: HookListProps) => { +export const HookList = ({ + schema, + filterString, + editHook = noop, + deleteHook = noop, +}: HookListProps) => { const { ref } = useParams() const { data: project } = useSelectedProjectQuery() const { data: hooks } = useDatabaseHooksQuery({ @@ -39,16 +45,19 @@ const HookList = ({ schema, filterString, editHook = noop, deleteHook = noop }: const restUrlTld = restUrl ? new URL(restUrl).hostname.split('.').pop() : 'co' const filteredHooks = (hooks ?? []).filter( - (x: any) => + (x) => includes(x.name.toLowerCase(), filterString.toLowerCase()) && x.schema === schema && x.function_args.length >= 2 ) - const canUpdateWebhook = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'triggers') + const { can: canUpdateWebhook } = useAsyncCheckProjectPermissions( + PermissionAction.TENANT_SQL_ADMIN_WRITE, + 'triggers' + ) return ( <> - {filteredHooks.map((x: any) => { + {filteredHooks.map((x) => { const isEdgeFunction = (url: string) => url.includes(`https://${ref}.functions.supabase.${restUrlTld}/`) || url.includes(`https://${ref}.supabase.${restUrlTld}/functions/`) @@ -134,5 +143,3 @@ const HookList = ({ schema, filterString, editHook = noop, deleteHook = noop }: ) } - -export default HookList diff --git a/apps/studio/components/interfaces/Database/Hooks/HooksList/HooksList.tsx b/apps/studio/components/interfaces/Database/Hooks/HooksList/HooksList.tsx index e255efb78d0da..7340883f745d6 100644 --- a/apps/studio/components/interfaces/Database/Hooks/HooksList/HooksList.tsx +++ b/apps/studio/components/interfaces/Database/Hooks/HooksList/HooksList.tsx @@ -1,3 +1,4 @@ +import { PostgresTrigger } from '@supabase/postgres-meta' import { PermissionAction } from '@supabase/shared-types/out/constants' import { includes, map as lodashMap, uniqBy } from 'lodash' import { Search } from 'lucide-react' @@ -9,20 +10,27 @@ import { DocsButton } from 'components/ui/DocsButton' import NoSearchResults from 'components/ui/NoSearchResults' import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader' import { useDatabaseHooksQuery } from 'data/database-triggers/database-triggers-query' -import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions' +import { + useAsyncCheckProjectPermissions, + usePermissionsLoaded, +} from 'hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { noop } from 'lib/void' import { Input } from 'ui' -import HooksListEmpty from './HooksListEmpty' -import SchemaTable from './SchemaTable' +import { HooksListEmpty } from './HooksListEmpty' +import { SchemaTable } from './SchemaTable' export interface HooksListProps { createHook: () => void - editHook: (hook: any) => void - deleteHook: (hook: any) => void + editHook: (hook: PostgresTrigger) => void + deleteHook: (hook: PostgresTrigger) => void } -const HooksList = ({ createHook = noop, editHook = noop, deleteHook = noop }: HooksListProps) => { +export const HooksList = ({ + createHook = noop, + editHook = noop, + deleteHook = noop, +}: HooksListProps) => { const { data: project } = useSelectedProjectQuery() const { data: hooks, @@ -41,7 +49,10 @@ const HooksList = ({ createHook = noop, editHook = noop, deleteHook = noop }: Ho ) const filteredHookSchemas = lodashMap(uniqBy(filteredHooks, 'schema'), 'schema') - const canCreateWebhooks = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'triggers') + const { can: canCreateWebhooks } = useAsyncCheckProjectPermissions( + PermissionAction.TENANT_SQL_ADMIN_WRITE, + 'triggers' + ) const isPermissionsLoaded = usePermissionsLoaded() return ( @@ -108,5 +119,3 @@ const HooksList = ({ createHook = noop, editHook = noop, deleteHook = noop }: Ho
) } - -export default HooksList diff --git a/apps/studio/components/interfaces/Database/Hooks/HooksList/HooksListEmpty.tsx b/apps/studio/components/interfaces/Database/Hooks/HooksList/HooksListEmpty.tsx index 2d466c0708b5c..0aa73a04c318e 100644 --- a/apps/studio/components/interfaces/Database/Hooks/HooksList/HooksListEmpty.tsx +++ b/apps/studio/components/interfaces/Database/Hooks/HooksList/HooksListEmpty.tsx @@ -1,6 +1,6 @@ import Table from 'components/to-be-cleaned/Table' -const HooksListEmpty = () => { +export const HooksListEmpty = () => { return ( { /> ) } - -export default HooksListEmpty diff --git a/apps/studio/components/interfaces/Database/Hooks/HooksList/SchemaTable.tsx b/apps/studio/components/interfaces/Database/Hooks/HooksList/SchemaTable.tsx index 52e0f48afdc09..0ebbc7dcd7650 100644 --- a/apps/studio/components/interfaces/Database/Hooks/HooksList/SchemaTable.tsx +++ b/apps/studio/components/interfaces/Database/Hooks/HooksList/SchemaTable.tsx @@ -1,16 +1,17 @@ +import { PostgresTrigger } from '@supabase/postgres-meta' import { noop } from 'lodash' import Table from 'components/to-be-cleaned/Table' -import HookList from './HookList' +import { HookList } from './HookList' interface SchemaTableProps { schema: string filterString: string - editHook: (hook: any) => void - deleteHook: (hook: any) => void + editHook: (hook: PostgresTrigger) => void + deleteHook: (hook: PostgresTrigger) => void } -const SchemaTable = ({ +export const SchemaTable = ({ schema, filterString, editHook = noop, @@ -55,5 +56,3 @@ const SchemaTable = ({ ) } - -export default SchemaTable diff --git a/apps/studio/components/interfaces/Database/Publications/PublicationsList.tsx b/apps/studio/components/interfaces/Database/Publications/PublicationsList.tsx index cd47055410a17..f24078292b20b 100644 --- a/apps/studio/components/interfaces/Database/Publications/PublicationsList.tsx +++ b/apps/studio/components/interfaces/Database/Publications/PublicationsList.tsx @@ -1,18 +1,18 @@ import { PermissionAction } from '@supabase/shared-types/out/constants' import { noop } from 'lodash' +import { AlertCircle, Search } from 'lucide-react' import { useState } from 'react' import { toast } from 'sonner' import { Button, Input, Toggle } from 'ui' -import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' import Table from 'components/to-be-cleaned/Table' import InformationBox from 'components/ui/InformationBox' import NoSearchResults from 'components/ui/NoSearchResults' import { useDatabasePublicationsQuery } from 'data/database-publications/database-publications-query' import { useDatabasePublicationUpdateMutation } from 'data/database-publications/database-publications-update-mutation' -import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' -import { AlertCircle, Search } from 'lucide-react' +import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' import PublicationSkeleton from './PublicationSkeleton' interface PublicationEvent { @@ -24,7 +24,7 @@ interface PublicationsListProps { onSelectPublication: (id: number) => void } -const PublicationsList = ({ onSelectPublication = noop }: PublicationsListProps) => { +export const PublicationsList = ({ onSelectPublication = noop }: PublicationsListProps) => { const { data: project } = useSelectedProjectQuery() const [filterString, setFilterString] = useState('') @@ -39,11 +39,8 @@ const PublicationsList = ({ onSelectPublication = noop }: PublicationsListProps) }, }) - const canUpdatePublications = useCheckPermissions( - PermissionAction.TENANT_SQL_ADMIN_WRITE, - 'publications' - ) - const isPermissionsLoaded = usePermissionsLoaded() + const { can: canUpdatePublications, isSuccess: isPermissionsLoaded } = + useAsyncCheckProjectPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'publications') const publicationEvents: PublicationEvent[] = [ { event: 'Insert', key: 'publish_insert' }, @@ -183,5 +180,3 @@ const PublicationsList = ({ onSelectPublication = noop }: PublicationsListProps) ) } - -export default PublicationsList diff --git a/apps/studio/components/interfaces/Database/Publications/PublicationsTableItem.tsx b/apps/studio/components/interfaces/Database/Publications/PublicationsTableItem.tsx index 0628aefae27a0..0ae7b75c7f993 100644 --- a/apps/studio/components/interfaces/Database/Publications/PublicationsTableItem.tsx +++ b/apps/studio/components/interfaces/Database/Publications/PublicationsTableItem.tsx @@ -1,13 +1,13 @@ import type { PostgresPublication, PostgresTable } from '@supabase/postgres-meta' import { PermissionAction } from '@supabase/shared-types/out/constants' import { useState } from 'react' -import { Badge, Toggle } from 'ui' +import { toast } from 'sonner' import Table from 'components/to-be-cleaned/Table' import { useDatabasePublicationUpdateMutation } from 'data/database-publications/database-publications-update-mutation' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' -import { toast } from 'sonner' +import { Badge, Toggle } from 'ui' interface PublicationsTableItemProps { table: PostgresTable @@ -22,7 +22,7 @@ const PublicationsTableItem = ({ table, selectedPublication }: PublicationsTable selectedPublication.tables?.find((x: any) => x.id == table.id) != undefined ) - const canUpdatePublications = useCheckPermissions( + const { can: canUpdatePublications } = useAsyncCheckProjectPermissions( PermissionAction.TENANT_SQL_ADMIN_WRITE, 'publications' ) diff --git a/apps/studio/components/interfaces/Database/Publications/PublicationsTables.tsx b/apps/studio/components/interfaces/Database/Publications/PublicationsTables.tsx index 01b65876670b9..ec191ac0ce781 100644 --- a/apps/studio/components/interfaces/Database/Publications/PublicationsTables.tsx +++ b/apps/studio/components/interfaces/Database/Publications/PublicationsTables.tsx @@ -1,18 +1,18 @@ import type { PostgresPublication } from '@supabase/postgres-meta' import { PermissionAction } from '@supabase/shared-types/out/constants' +import { ChevronLeft, Search } from 'lucide-react' import { useMemo, useState } from 'react' import NoSearchResults from 'components/to-be-cleaned/NoSearchResults' import Table from 'components/to-be-cleaned/Table' import AlertError from 'components/ui/AlertError' -import InformationBox from 'components/ui/InformationBox' import { Loading } from 'components/ui/Loading' import { useTablesQuery } from 'data/tables/tables-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { useProtectedSchemas } from 'hooks/useProtectedSchemas' -import { AlertCircle, ChevronLeft, Search } from 'lucide-react' import { Button, Input } from 'ui' +import { Admonition } from 'ui-patterns' import PublicationsTableItem from './PublicationsTableItem' interface PublicationsTablesProps { @@ -20,14 +20,15 @@ interface PublicationsTablesProps { onSelectBack: () => void } -const PublicationsTables = ({ selectedPublication, onSelectBack }: PublicationsTablesProps) => { +export const PublicationsTables = ({ + selectedPublication, + onSelectBack, +}: PublicationsTablesProps) => { const { data: project } = useSelectedProjectQuery() const [filterString, setFilterString] = useState('') - const canUpdatePublications = useCheckPermissions( - PermissionAction.TENANT_SQL_ADMIN_WRITE, - 'publications' - ) + const { can: canUpdatePublications, isLoading: isLoadingPermissions } = + useAsyncCheckProjectPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'publications') const { data: protectedSchemas } = useProtectedSchemas() @@ -71,17 +72,17 @@ const PublicationsTables = ({ selectedPublication, onSelectBack }: PublicationsT /> - {!canUpdatePublications && ( -
- } - title="You need additional permissions to update database replications" - /> -
+ {!isLoadingPermissions && !canUpdatePublications && ( + )} - {isLoading && ( + + {(isLoading || isLoadingPermissions) && (
@@ -131,5 +132,3 @@ const PublicationsTables = ({ selectedPublication, onSelectBack }: PublicationsT ) } - -export default PublicationsTables diff --git a/apps/studio/components/interfaces/Database/Roles/CreateRolePanel.tsx b/apps/studio/components/interfaces/Database/Roles/CreateRolePanel.tsx index 0d60481619695..7381c5968cf03 100644 --- a/apps/studio/components/interfaces/Database/Roles/CreateRolePanel.tsx +++ b/apps/studio/components/interfaces/Database/Roles/CreateRolePanel.tsx @@ -44,7 +44,7 @@ const initialValues = { canBypassRls: false, } -const CreateRolePanel = ({ visible, onClose }: CreateRolePanelProps) => { +export const CreateRolePanel = ({ visible, onClose }: CreateRolePanelProps) => { const formId = 'create-new-role' const { data: project } = useSelectedProjectQuery() @@ -187,5 +187,3 @@ const CreateRolePanel = ({ visible, onClose }: CreateRolePanelProps) => { ) } - -export default CreateRolePanel diff --git a/apps/studio/components/interfaces/Database/Roles/DeleteRoleModal.tsx b/apps/studio/components/interfaces/Database/Roles/DeleteRoleModal.tsx index 9ae12e4575317..91f868bc7b898 100644 --- a/apps/studio/components/interfaces/Database/Roles/DeleteRoleModal.tsx +++ b/apps/studio/components/interfaces/Database/Roles/DeleteRoleModal.tsx @@ -11,7 +11,7 @@ interface DeleteRoleModalProps { onClose: () => void } -const DeleteRoleModal = ({ role, visible, onClose }: DeleteRoleModalProps) => { +export const DeleteRoleModal = ({ role, visible, onClose }: DeleteRoleModalProps) => { const { data: project } = useSelectedProjectQuery() const { mutate: deleteDatabaseRole, isLoading: isDeleting } = useDatabaseRoleDeleteMutation({ @@ -50,5 +50,3 @@ const DeleteRoleModal = ({ role, visible, onClose }: DeleteRoleModalProps) => { ) } - -export default DeleteRoleModal diff --git a/apps/studio/components/interfaces/Database/Roles/RoleRow.tsx b/apps/studio/components/interfaces/Database/Roles/RoleRow.tsx index 5f109a3597a7b..876ffea6e0169 100644 --- a/apps/studio/components/interfaces/Database/Roles/RoleRow.tsx +++ b/apps/studio/components/interfaces/Database/Roles/RoleRow.tsx @@ -27,7 +27,7 @@ interface RoleRowProps { onSelectDelete: (role: PgRole) => void } -const RoleRow = ({ role, disabled = false, onSelectDelete }: RoleRowProps) => { +export const RoleRow = ({ role, disabled = false, onSelectDelete }: RoleRowProps) => { const { data: project } = useSelectedProjectQuery() const [isExpanded, setIsExpanded] = useState(false) @@ -219,5 +219,3 @@ const RoleRow = ({ role, disabled = false, onSelectDelete }: RoleRowProps) => { ) } - -export default RoleRow diff --git a/apps/studio/components/interfaces/Database/Roles/RoleRowSkeleton.tsx b/apps/studio/components/interfaces/Database/Roles/RoleRowSkeleton.tsx index b0ef4317008f9..1b127aae5d636 100644 --- a/apps/studio/components/interfaces/Database/Roles/RoleRowSkeleton.tsx +++ b/apps/studio/components/interfaces/Database/Roles/RoleRowSkeleton.tsx @@ -6,7 +6,7 @@ export interface RoleRowSkeletonProps { index?: number } -const RoleRowSkeleton = ({ index }: RoleRowSkeletonProps) => { +export const RoleRowSkeleton = ({ index }: RoleRowSkeletonProps) => { return (
{
) } - -export default RoleRowSkeleton diff --git a/apps/studio/components/interfaces/Database/Roles/RolesList.tsx b/apps/studio/components/interfaces/Database/Roles/RolesList.tsx index 47568a0768e88..1385c807f34a1 100644 --- a/apps/studio/components/interfaces/Database/Roles/RolesList.tsx +++ b/apps/studio/components/interfaces/Database/Roles/RolesList.tsx @@ -8,13 +8,13 @@ import NoSearchResults from 'components/ui/NoSearchResults' import SparkBar from 'components/ui/SparkBar' import { useDatabaseRolesQuery } from 'data/database-roles/database-roles-query' import { useMaxConnectionsQuery } from 'data/database/max-connections-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { Badge, Button, Input, Tooltip, TooltipContent, TooltipTrigger } from 'ui' -import CreateRolePanel from './CreateRolePanel' -import DeleteRoleModal from './DeleteRoleModal' -import RoleRow from './RoleRow' -import RoleRowSkeleton from './RoleRowSkeleton' +import { CreateRolePanel } from './CreateRolePanel' +import { DeleteRoleModal } from './DeleteRoleModal' +import { RoleRow } from './RoleRow' +import { RoleRowSkeleton } from './RoleRowSkeleton' import { SUPABASE_ROLES } from './Roles.constants' type SUPABASE_ROLE = (typeof SUPABASE_ROLES)[number] @@ -27,7 +27,10 @@ const RolesList = () => { const [isCreatingRole, setIsCreatingRole] = useState(false) const [selectedRoleToDelete, setSelectedRoleToDelete] = useState() - const canUpdateRoles = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'roles') + const { can: canUpdateRoles } = useAsyncCheckProjectPermissions( + PermissionAction.TENANT_SQL_ADMIN_WRITE, + 'roles' + ) const { data: maxConnData } = useMaxConnectionsQuery({ projectRef: project?.ref, diff --git a/apps/studio/components/interfaces/Database/Tables/ColumnList.tsx b/apps/studio/components/interfaces/Database/Tables/ColumnList.tsx index ba4eedf98394c..83aaf0cacef96 100644 --- a/apps/studio/components/interfaces/Database/Tables/ColumnList.tsx +++ b/apps/studio/components/interfaces/Database/Tables/ColumnList.tsx @@ -4,6 +4,7 @@ import { Check, ChevronLeft, Edit, MoreVertical, Plus, Search, Trash, X } from ' import Link from 'next/link' import { useState } from 'react' +import { PostgresColumn } from '@supabase/postgres-meta' import { useParams } from 'common' import NoSearchResults from 'components/to-be-cleaned/NoSearchResults' import Table from 'components/to-be-cleaned/Table' @@ -12,7 +13,7 @@ import { ButtonTooltip } from 'components/ui/ButtonTooltip' import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader' import { useTableEditorQuery } from 'data/table-editor/table-editor-query' import { isTableLike } from 'data/table-editor/table-editor-types' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { useIsProtectedSchema } from 'hooks/useProtectedSchemas' import { @@ -30,11 +31,11 @@ import { ProtectedSchemaWarning } from '../ProtectedSchemaWarning' interface ColumnListProps { onAddColumn: () => void - onEditColumn: (column: any) => void - onDeleteColumn: (column: any) => void + onEditColumn: (column: PostgresColumn) => void + onDeleteColumn: (column: PostgresColumn) => void } -const ColumnList = ({ +export const ColumnList = ({ onAddColumn = noop, onEditColumn = noop, onDeleteColumn = noop, @@ -64,7 +65,10 @@ const ColumnList = ({ : selectedTable?.columns?.filter((column) => column.name.includes(filterString))) ?? [] const { isSchemaLocked } = useIsProtectedSchema({ schema: selectedTable?.schema ?? '' }) - const canUpdateColumns = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'columns') + const { can: canUpdateColumns } = useAsyncCheckProjectPermissions( + PermissionAction.TENANT_SQL_ADMIN_WRITE, + 'columns' + ) return (
@@ -213,5 +217,3 @@ const ColumnList = ({
) } - -export default ColumnList diff --git a/apps/studio/components/interfaces/Database/Tables/TableList.tsx b/apps/studio/components/interfaces/Database/Tables/TableList.tsx index c3eea9f3055aa..68e4ead2a1432 100644 --- a/apps/studio/components/interfaces/Database/Tables/TableList.tsx +++ b/apps/studio/components/interfaces/Database/Tables/TableList.tsx @@ -23,6 +23,7 @@ import { useParams } from 'common' import Table from 'components/to-be-cleaned/Table' import AlertError from 'components/ui/AlertError' import { ButtonTooltip } from 'components/ui/ButtonTooltip' +import { DropdownMenuItemTooltip } from 'components/ui/DropdownMenuItemTooltip' import SchemaSelector from 'components/ui/SchemaSelector' import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader' import { useDatabasePublicationsQuery } from 'data/database-publications/database-publications-query' @@ -32,7 +33,7 @@ import { useMaterializedViewsQuery } from 'data/materialized-views/materialized- import { usePrefetchEditorTablePage } from 'data/prefetchers/project.$ref.editor.$id' import { useTablesQuery } from 'data/tables/tables-query' import { useViewsQuery } from 'data/views/views-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useQuerySchemaState } from 'hooks/misc/useSchemaQueryState' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { useIsProtectedSchema } from 'hooks/useProtectedSchemas' @@ -64,7 +65,7 @@ interface TableListProps { onDuplicateTable: (table: PostgresTable) => void } -const TableList = ({ +export const TableList = ({ onDuplicateTable, onAddTable = noop, onEditTable = noop, @@ -80,7 +81,11 @@ const TableList = ({ const [filterString, setFilterString] = useState('') const [visibleTypes, setVisibleTypes] = useState(Object.values(ENTITY_TYPE)) - const canUpdateTables = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'tables') + + const { can: canUpdateTables } = useAsyncCheckProjectPermissions( + PermissionAction.TENANT_SQL_ADMIN_WRITE, + 'tables' + ) const { data: tables, @@ -484,62 +489,58 @@ const TableList = ({ {x.type === ENTITY_TYPE.TABLE && ( <> - - - { - if (canUpdateTables) onEditTable(x) - }} - > - -

Edit table

-
-
- {!canUpdateTables && ( - - You need additional permissions to edit this table - - )} -
- { + if (canUpdateTables) onEditTable(x) + }} + tooltip={{ + content: { + side: 'left', + text: 'You need additional permissions to edit this table', + }, + }} + > + +

Edit table

+ + { - e.stopPropagation() - if (canUpdateTables) { - onDuplicateTable(x) - } + className="gap-x-2" + disabled={!canUpdateTables} + onClick={() => { + if (canUpdateTables) onDuplicateTable(x) + }} + tooltip={{ + content: { + side: 'left', + text: 'You need additional permissions to duplicate tables', + }, }} > Duplicate Table -
- - - { - if (canUpdateTables && !isSchemaLocked) { - onDeleteTable({ - ...x, - schema: selectedSchema, - }) - } - }} - > - -

Delete table

-
-
- {!canUpdateTables && ( - - You need additional permissions to delete tables - - )} -
+ + + { + if (canUpdateTables && !isSchemaLocked) { + onDeleteTable({ ...x, schema: selectedSchema }) + } + }} + tooltip={{ + content: { + side: 'left', + text: 'You need additional permissions to delete tables', + }, + }} + > + +

Delete table

+
)} @@ -557,5 +558,3 @@ const TableList = ({ ) } - -export default TableList diff --git a/apps/studio/components/interfaces/Database/Triggers/TriggersList/TriggerList.tsx b/apps/studio/components/interfaces/Database/Triggers/TriggersList/TriggerList.tsx index 809b5d65bcc97..cc3f4b5283f81 100644 --- a/apps/studio/components/interfaces/Database/Triggers/TriggersList/TriggerList.tsx +++ b/apps/studio/components/interfaces/Database/Triggers/TriggersList/TriggerList.tsx @@ -5,7 +5,7 @@ import { Check, Edit, Edit2, MoreVertical, Trash, X } from 'lucide-react' import Table from 'components/to-be-cleaned/Table' import { ButtonTooltip } from 'components/ui/ButtonTooltip' import { useDatabaseTriggersQuery } from 'data/database-triggers/database-triggers-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { useAiAssistantStateSnapshot } from 'state/ai-assistant-state' import { @@ -51,7 +51,10 @@ const TriggerList = ({ filteredTriggers.filter((x) => x.schema == schema), (trigger) => trigger.name.toLocaleLowerCase() ) - const canUpdateTriggers = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'triggers') + const { can: canUpdateTriggers } = useAsyncCheckProjectPermissions( + PermissionAction.TENANT_SQL_ADMIN_WRITE, + 'triggers' + ) if (_triggers.length === 0 && filterString.length === 0) { return ( diff --git a/apps/studio/components/interfaces/Database/Triggers/TriggersList/TriggersList.tsx b/apps/studio/components/interfaces/Database/Triggers/TriggersList/TriggersList.tsx index 6cb57562621e3..2978d9d307489 100644 --- a/apps/studio/components/interfaces/Database/Triggers/TriggersList/TriggersList.tsx +++ b/apps/studio/components/interfaces/Database/Triggers/TriggersList/TriggersList.tsx @@ -13,7 +13,7 @@ import SchemaSelector from 'components/ui/SchemaSelector' import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader' import { useDatabaseTriggersQuery } from 'data/database-triggers/database-triggers-query' import { useTablesQuery } from 'data/tables/tables-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useQuerySchemaState } from 'hooks/misc/useSchemaQueryState' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { useIsProtectedSchema, useProtectedSchemas } from 'hooks/useProtectedSchemas' @@ -41,7 +41,7 @@ const TriggersList = ({ const { data: protectedSchemas } = useProtectedSchemas() const { isSchemaLocked } = useIsProtectedSchema({ schema: selectedSchema }) - const { data = [], isSuccess } = useTablesQuery({ + const { data = [] } = useTablesQuery({ projectRef: project?.ref, connectionString: project?.connectionString, }) @@ -58,7 +58,10 @@ const TriggersList = ({ connectionString: project?.connectionString, }) - const canCreateTriggers = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'triggers') + const { can: canCreateTriggers } = useAsyncCheckProjectPermissions( + PermissionAction.TENANT_SQL_ADMIN_WRITE, + 'triggers' + ) if (isLoading) { return diff --git a/apps/studio/components/interfaces/Database/index.ts b/apps/studio/components/interfaces/Database/index.ts index 0667d17b0dc48..0269df1734528 100644 --- a/apps/studio/components/interfaces/Database/index.ts +++ b/apps/studio/components/interfaces/Database/index.ts @@ -1,13 +1,7 @@ -export { default as ColumnList } from './Tables/ColumnList' -export { default as TableList } from './Tables/TableList' - export { default as RolesList } from './Roles/RolesList' export { default as Extensions } from './Extensions/Extensions' -export { default as PublicationsList } from './Publications/PublicationsList' -export { default as PublicationsTables } from './Publications/PublicationsTables' - export { default as BackupsList } from './Backups/BackupsList' export { default as CreateFunction } from './Functions/CreateFunction' diff --git a/apps/studio/components/interfaces/Integrations/Webhooks/ListTab.tsx b/apps/studio/components/interfaces/Integrations/Webhooks/ListTab.tsx index 9212fe9480155..2e87e67a2092d 100644 --- a/apps/studio/components/interfaces/Integrations/Webhooks/ListTab.tsx +++ b/apps/studio/components/interfaces/Integrations/Webhooks/ListTab.tsx @@ -1,31 +1,34 @@ +import { PostgresTrigger } from '@supabase/postgres-meta' import { PermissionAction } from '@supabase/shared-types/out/constants' import { useState } from 'react' import DeleteHookModal from 'components/interfaces/Database/Hooks/DeleteHookModal' import { EditHookPanel } from 'components/interfaces/Database/Hooks/EditHookPanel' -import HooksList from 'components/interfaces/Database/Hooks/HooksList/HooksList' +import { HooksList } from 'components/interfaces/Database/Hooks/HooksList/HooksList' import NoPermission from 'components/ui/NoPermission' -import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' export const WebhooksListTab = () => { const [selectedHook, setSelectedHook] = useState() const [showCreateHookForm, setShowCreateHookForm] = useState(false) const [showDeleteHookForm, setShowDeleteHookForm] = useState(false) - const canReadWebhooks = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_READ, 'triggers') - const isPermissionsLoaded = usePermissionsLoaded() + const { can: canReadWebhooks, isSuccess: isPermissionsLoaded } = useAsyncCheckProjectPermissions( + PermissionAction.TENANT_SQL_ADMIN_READ, + 'triggers' + ) const createHook = () => { setSelectedHook(undefined) setShowCreateHookForm(true) } - const editHook = (hook: any) => { + const editHook = (hook: PostgresTrigger) => { setSelectedHook(hook) setShowCreateHookForm(true) } - const deleteHook = (hook: any) => { + const deleteHook = (hook: PostgresTrigger) => { setSelectedHook(hook) setShowDeleteHookForm(true) } diff --git a/apps/studio/components/interfaces/Realtime/Inspector/Header.tsx b/apps/studio/components/interfaces/Realtime/Inspector/Header.tsx index d1bdff3faf327..867438923c1d7 100644 --- a/apps/studio/components/interfaces/Realtime/Inspector/Header.tsx +++ b/apps/studio/components/interfaces/Realtime/Inspector/Header.tsx @@ -1,9 +1,11 @@ +import { PermissionAction } from '@supabase/shared-types/out/constants' import { PlayCircle, StopCircle } from 'lucide-react' import { Dispatch, SetStateAction } from 'react' import { useParams } from 'common' import { ButtonTooltip } from 'components/ui/ButtonTooltip' import { useSendEventMutation } from 'data/telemetry/send-event-mutation' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization' import { ChooseChannelPopover } from './ChooseChannelPopover' import { RealtimeFilterPopover } from './RealtimeFilterPopover' @@ -20,6 +22,11 @@ export const Header = ({ config, onChangeConfig }: HeaderProps) => { const { ref } = useParams() const { data: org } = useSelectedOrganizationQuery() + const { can: canReadAPIKeys } = useAsyncCheckProjectPermissions( + PermissionAction.READ, + 'service_api_keys' + ) + return (
@@ -29,7 +36,7 @@ export const Header = ({ config, onChangeConfig }: HeaderProps) => { size="tiny" type={config.enabled ? 'warning' : 'primary'} className="rounded-l-none border-l-0" - disabled={config.channelName.length === 0} + disabled={!canReadAPIKeys || config.channelName.length === 0} icon={config.enabled ? : } onClick={() => { onChangeConfig({ ...config, enabled: !config.enabled }) @@ -47,8 +54,11 @@ export const Header = ({ config, onChangeConfig }: HeaderProps) => { tooltip={{ content: { side: 'bottom', - text: - config.channelName.length === 0 ? 'You need to join a channel first' : undefined, + text: !canReadAPIKeys + ? 'You need additional permissions to use the realtime inspector' + : config.channelName.length === 0 + ? 'You need to join a channel first' + : undefined, }, }} > diff --git a/apps/studio/components/interfaces/Realtime/Inspector/MessagesTable.tsx b/apps/studio/components/interfaces/Realtime/Inspector/MessagesTable.tsx index 95fd72a350a4c..8f5a24e2d41ea 100644 --- a/apps/studio/components/interfaces/Realtime/Inspector/MessagesTable.tsx +++ b/apps/studio/components/interfaces/Realtime/Inspector/MessagesTable.tsx @@ -1,3 +1,4 @@ +import { PermissionAction } from '@supabase/shared-types/out/constants' import { isEqual } from 'lodash' import { ExternalLink, Loader2, Megaphone } from 'lucide-react' import Link from 'next/link' @@ -6,10 +7,13 @@ import DataGrid, { Row } from 'react-data-grid' import { useParams } from 'common' import { DocsButton } from 'components/ui/DocsButton' +import NoPermission from 'components/ui/NoPermission' import ShimmerLine from 'components/ui/ShimmerLine' import { useSendEventMutation } from 'data/telemetry/send-event-mutation' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization' import { Button, IconBroadcast, IconDatabaseChanges, IconPresence, cn } from 'ui' +import { GenericSkeletonLoader } from 'ui-patterns' import MessageSelection from './MessageSelection' import type { LogData } from './Messages.types' import NoChannelEmptyState from './NoChannelEmptyState' @@ -30,9 +34,18 @@ const NoResultAlert = ({ }) => { const { ref } = useParams() + const { can: canReadAPIKeys, isLoading: isLoadingPermissions } = useAsyncCheckProjectPermissions( + PermissionAction.READ, + 'service_api_keys' + ) + return (
- {!hasChannelSet ? ( + {isLoadingPermissions ? ( + + ) : !canReadAPIKeys ? ( + + ) : !hasChannelSet ? ( ) : ( <> diff --git a/apps/studio/components/interfaces/Realtime/Inspector/index.tsx b/apps/studio/components/interfaces/Realtime/Inspector/index.tsx index f742ea955e339..28b616b773593 100644 --- a/apps/studio/components/interfaces/Realtime/Inspector/index.tsx +++ b/apps/studio/components/interfaces/Realtime/Inspector/index.tsx @@ -14,8 +14,8 @@ import { RealtimeConfig, useRealtimeMessages } from './useRealtimeMessages' export const RealtimeInspector = () => { const { ref } = useParams() const { data: org } = useSelectedOrganizationQuery() - const [sendMessageShown, setSendMessageShown] = useState(false) + const [sendMessageShown, setSendMessageShown] = useState(false) const [realtimeConfig, setRealtimeConfig] = useState({ enabled: false, projectRef: ref!, diff --git a/apps/studio/components/ui/SchemaSelector.tsx b/apps/studio/components/ui/SchemaSelector.tsx index d11e97581f0f0..72bd031de5b6e 100644 --- a/apps/studio/components/ui/SchemaSelector.tsx +++ b/apps/studio/components/ui/SchemaSelector.tsx @@ -3,7 +3,7 @@ import { Check, ChevronsUpDown, Plus } from 'lucide-react' import { useState } from 'react' import { useSchemasQuery } from 'data/database/schemas-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { AlertDescription_Shadcn_, @@ -50,7 +50,10 @@ const SchemaSelector = ({ portal = true, }: SchemaSelectorProps) => { const [open, setOpen] = useState(false) - const canCreateSchemas = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'schemas') + const { can: canCreateSchemas } = useAsyncCheckProjectPermissions( + PermissionAction.TENANT_SQL_ADMIN_WRITE, + 'schemas' + ) const { data: project } = useSelectedProjectQuery() const { diff --git a/apps/studio/data/database-triggers/database-triggers-query.ts b/apps/studio/data/database-triggers/database-triggers-query.ts index faa78e23fc211..5b80cc9fc3ec2 100644 --- a/apps/studio/data/database-triggers/database-triggers-query.ts +++ b/apps/studio/data/database-triggers/database-triggers-query.ts @@ -1,8 +1,8 @@ +import { DEFAULT_PLATFORM_APPLICATION_NAME } from '@supabase/pg-meta/src/constants' import { useQuery, UseQueryOptions } from '@tanstack/react-query' import { get, handleError } from 'data/fetchers' import type { ResponseError } from 'types' import { databaseTriggerKeys } from './keys' -import { DEFAULT_PLATFORM_APPLICATION_NAME } from '@supabase/pg-meta/src/constants' export type DatabaseTriggersVariables = { projectRef?: string diff --git a/apps/studio/pages/project/[ref]/branches/index.tsx b/apps/studio/pages/project/[ref]/branches/index.tsx index befbcd4927173..006d7b5ff28b0 100644 --- a/apps/studio/pages/project/[ref]/branches/index.tsx +++ b/apps/studio/pages/project/[ref]/branches/index.tsx @@ -19,7 +19,7 @@ import { useBranchDeleteMutation } from 'data/branches/branch-delete-mutation' import { Branch, useBranchesQuery } from 'data/branches/branches-query' import { useGitHubConnectionsQuery } from 'data/integrations/github-connections-query' import { useSendEventMutation } from 'data/telemetry/send-event-mutation' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { useAppStateSnapshot } from 'state/app-state' @@ -42,7 +42,10 @@ const BranchesPage: NextPageWithLayout = () => { const projectRef = project !== undefined ? (isBranch ? project.parent_project_ref : ref) : undefined - const canReadBranches = useCheckPermissions(PermissionAction.READ, 'preview_branches') + const { can: canReadBranches, isSuccess: isPermissionsLoaded } = useAsyncCheckProjectPermissions( + PermissionAction.READ, + 'preview_branches' + ) const { data: connections, @@ -121,7 +124,7 @@ const BranchesPage: NextPageWithLayout = () => {
- {!canReadBranches ? ( + {isPermissionsLoaded && !canReadBranches ? ( ) : ( <> @@ -183,9 +186,13 @@ const BranchesPage: NextPageWithLayout = () => { BranchesPage.getLayout = (page) => { const BranchesPageWrapper = () => { const snap = useAppStateSnapshot() - const canCreateBranches = useCheckPermissions(PermissionAction.CREATE, 'preview_branches', { - resource: { is_default: false }, - }) + const { can: canCreateBranches } = useAsyncCheckProjectPermissions( + PermissionAction.CREATE, + 'preview_branches', + { + resource: { is_default: false }, + } + ) const primaryActions = ( { const projectRef = project !== undefined ? (isBranch ? project.parent_project_ref : ref) : undefined - const canReadBranches = useCheckPermissions(PermissionAction.READ, 'preview_branches') + const { can: canReadBranches, isSuccess: isPermissionsLoaded } = useAsyncCheckProjectPermissions( + PermissionAction.READ, + 'preview_branches' + ) const { data: connections, @@ -163,7 +166,7 @@ const MergeRequestsPage: NextPageWithLayout = () => {
- {!canReadBranches ? ( + {isPermissionsLoaded && !canReadBranches ? ( ) : ( <> diff --git a/apps/studio/pages/project/[ref]/database/backups/pitr.tsx b/apps/studio/pages/project/[ref]/database/backups/pitr.tsx index b66eb6904d118..ae534f92f1320 100644 --- a/apps/studio/pages/project/[ref]/database/backups/pitr.tsx +++ b/apps/studio/pages/project/[ref]/database/backups/pitr.tsx @@ -14,7 +14,7 @@ import NoPermission from 'components/ui/NoPermission' import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader' import UpgradeToPro from 'components/ui/UpgradeToPro' import { useBackupsQuery } from 'data/database/backups-query' -import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization' import { useIsOrioleDbInAws, useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { PROJECT_STATUS } from 'lib/constants' @@ -57,8 +57,8 @@ const PITR = () => { const isEnabled = backups?.pitr_enabled const isActiveHealthy = project?.status === PROJECT_STATUS.ACTIVE_HEALTHY - const isPermissionsLoaded = usePermissionsLoaded() - const canReadPhysicalBackups = useCheckPermissions(PermissionAction.READ, 'physical_backups') + const { can: canReadPhysicalBackups, isSuccess: isPermissionsLoaded } = + useAsyncCheckProjectPermissions(PermissionAction.READ, 'physical_backups') if (isPermissionsLoaded && !canReadPhysicalBackups) { return diff --git a/apps/studio/pages/project/[ref]/database/backups/restore-to-new-project.tsx b/apps/studio/pages/project/[ref]/database/backups/restore-to-new-project.tsx index 1e186f17cddaa..31a58c8bccb4a 100644 --- a/apps/studio/pages/project/[ref]/database/backups/restore-to-new-project.tsx +++ b/apps/studio/pages/project/[ref]/database/backups/restore-to-new-project.tsx @@ -23,7 +23,7 @@ import UpgradeToPro from 'components/ui/UpgradeToPro' import { useDiskAttributesQuery } from 'data/config/disk-attributes-query' import { useCloneBackupsQuery } from 'data/projects/clone-query' import { useCloneStatusQuery } from 'data/projects/clone-status-query' -import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization' import { useIsAwsK8sCloudProvider, @@ -80,12 +80,11 @@ const RestoreToNewProject = () => { isError, } = useCloneBackupsQuery({ projectRef: project?.ref }, { enabled: !isFreePlan }) - const plan = organization?.plan?.id const isActiveHealthy = project?.status === PROJECT_STATUS.ACTIVE_HEALTHY - const isPermissionsLoaded = usePermissionsLoaded() - const canReadPhysicalBackups = useCheckPermissions(PermissionAction.READ, 'physical_backups') - const canTriggerPhysicalBackups = useCheckPermissions( + const { can: canReadPhysicalBackups, isSuccess: isPermissionsLoaded } = + useAsyncCheckProjectPermissions(PermissionAction.READ, 'physical_backups') + const { can: canTriggerPhysicalBackups } = useAsyncCheckProjectPermissions( PermissionAction.INFRA_EXECUTE, 'queue_job.restore.prepare' ) diff --git a/apps/studio/pages/project/[ref]/database/backups/scheduled.tsx b/apps/studio/pages/project/[ref]/database/backups/scheduled.tsx index e9f40c21891df..52b0838add596 100644 --- a/apps/studio/pages/project/[ref]/database/backups/scheduled.tsx +++ b/apps/studio/pages/project/[ref]/database/backups/scheduled.tsx @@ -14,7 +14,7 @@ import InformationBox from 'components/ui/InformationBox' import NoPermission from 'components/ui/NoPermission' import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader' import { useBackupsQuery } from 'data/database/backups-query' -import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useIsOrioleDbInAws } from 'hooks/misc/useSelectedProject' import type { NextPageWithLayout } from 'types' import { Admonition } from 'ui-patterns' @@ -26,9 +26,9 @@ const DatabaseScheduledBackups: NextPageWithLayout = () => { const isOrioleDbInAws = useIsOrioleDbInAws() const isPitrEnabled = backups?.pitr_enabled - const isPermissionsLoaded = usePermissionsLoaded() - const canReadScheduledBackups = useCheckPermissions(PermissionAction.READ, 'back_ups') + const { can: canReadScheduledBackups, isSuccess: isPermissionsLoaded } = + useAsyncCheckProjectPermissions(PermissionAction.READ, 'back_ups') return ( diff --git a/apps/studio/pages/project/[ref]/database/extensions.tsx b/apps/studio/pages/project/[ref]/database/extensions.tsx index d1c7a3565f460..fd663c2a53f34 100644 --- a/apps/studio/pages/project/[ref]/database/extensions.tsx +++ b/apps/studio/pages/project/[ref]/database/extensions.tsx @@ -6,15 +6,12 @@ import DefaultLayout from 'components/layouts/DefaultLayout' import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold' import { FormHeader } from 'components/ui/Forms/FormHeader' import NoPermission from 'components/ui/NoPermission' -import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import type { NextPageWithLayout } from 'types' const DatabaseExtensions: NextPageWithLayout = () => { - const canReadExtensions = useCheckPermissions( - PermissionAction.TENANT_SQL_ADMIN_READ, - 'extensions' - ) - const isPermissionsLoaded = usePermissionsLoaded() + const { can: canReadExtensions, isSuccess: isPermissionsLoaded } = + useAsyncCheckProjectPermissions(PermissionAction.TENANT_SQL_ADMIN_READ, 'extensions') if (isPermissionsLoaded && !canReadExtensions) { return diff --git a/apps/studio/pages/project/[ref]/database/functions.tsx b/apps/studio/pages/project/[ref]/database/functions.tsx index c4653c0b56b22..fc74e83002ada 100644 --- a/apps/studio/pages/project/[ref]/database/functions.tsx +++ b/apps/studio/pages/project/[ref]/database/functions.tsx @@ -11,7 +11,7 @@ import { EditorPanel } from 'components/ui/EditorPanel/EditorPanel' import { FormHeader } from 'components/ui/Forms/FormHeader' import NoPermission from 'components/ui/NoPermission' import { DatabaseFunction } from 'data/database-functions/database-functions-query' -import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import type { NextPageWithLayout } from 'types' const DatabaseFunctionsPage: NextPageWithLayout = () => { @@ -26,8 +26,10 @@ const DatabaseFunctionsPage: NextPageWithLayout = () => { DatabaseFunction | undefined >() - const canReadFunctions = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_READ, 'functions') - const isPermissionsLoaded = usePermissionsLoaded() + const { can: canReadFunctions, isSuccess: isPermissionsLoaded } = useAsyncCheckProjectPermissions( + PermissionAction.TENANT_SQL_ADMIN_READ, + 'functions' + ) const createFunction = () => { if (isInlineEditorEnabled) { diff --git a/apps/studio/pages/project/[ref]/database/publications.tsx b/apps/studio/pages/project/[ref]/database/publications.tsx index 06b0c5bbffd38..fb3d57b306042 100644 --- a/apps/studio/pages/project/[ref]/database/publications.tsx +++ b/apps/studio/pages/project/[ref]/database/publications.tsx @@ -1,14 +1,15 @@ import { PermissionAction } from '@supabase/shared-types/out/constants' import { useState } from 'react' -import { PublicationsList, PublicationsTables } from 'components/interfaces/Database' +import { PublicationsList } from 'components/interfaces/Database/Publications/PublicationsList' +import { PublicationsTables } from 'components/interfaces/Database/Publications/PublicationsTables' import DatabaseLayout from 'components/layouts/DatabaseLayout/DatabaseLayout' import DefaultLayout from 'components/layouts/DefaultLayout' import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold' import { FormHeader } from 'components/ui/Forms/FormHeader' import NoPermission from 'components/ui/NoPermission' import { useDatabasePublicationsQuery } from 'data/database-publications/database-publications-query' -import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import type { NextPageWithLayout } from 'types' @@ -25,11 +26,8 @@ const DatabasePublications: NextPageWithLayout = () => { }) const publications = data ?? [] - const canViewPublications = useCheckPermissions( - PermissionAction.TENANT_SQL_ADMIN_READ, - 'publications' - ) - const isPermissionsLoaded = usePermissionsLoaded() + const { can: canViewPublications, isSuccess: isPermissionsLoaded } = + useAsyncCheckProjectPermissions(PermissionAction.TENANT_SQL_ADMIN_READ, 'publications') const [selectedPublicationId, setSelectedPublicationId] = useState() const selectedPublication = publications.find((pub) => pub.id === selectedPublicationId) diff --git a/apps/studio/pages/project/[ref]/database/tables/[id].tsx b/apps/studio/pages/project/[ref]/database/tables/[id].tsx index 3a0cf30b1c2d4..4aece9c79a706 100644 --- a/apps/studio/pages/project/[ref]/database/tables/[id].tsx +++ b/apps/studio/pages/project/[ref]/database/tables/[id].tsx @@ -1,7 +1,7 @@ import { ChevronRight } from 'lucide-react' import { useParams } from 'common' -import { ColumnList } from 'components/interfaces/Database' +import { ColumnList } from 'components/interfaces/Database/Tables/ColumnList' import { SidePanelEditor } from 'components/interfaces/TableGridEditor' import DeleteConfirmationDialogs from 'components/interfaces/TableGridEditor/DeleteConfirmationDialogs' import DatabaseLayout from 'components/layouts/DatabaseLayout/DatabaseLayout' diff --git a/apps/studio/pages/project/[ref]/database/tables/index.tsx b/apps/studio/pages/project/[ref]/database/tables/index.tsx index 1b7075d19dcb0..9cd2e2d261d6b 100644 --- a/apps/studio/pages/project/[ref]/database/tables/index.tsx +++ b/apps/studio/pages/project/[ref]/database/tables/index.tsx @@ -1,8 +1,8 @@ -import { useState } from 'react' import { PostgresTable } from '@supabase/postgres-meta' +import { useState } from 'react' import { useParams } from 'common' -import { TableList } from 'components/interfaces/Database' +import { TableList } from 'components/interfaces/Database/Tables/TableList' import { SidePanelEditor } from 'components/interfaces/TableGridEditor' import DeleteConfirmationDialogs from 'components/interfaces/TableGridEditor/DeleteConfirmationDialogs' import DatabaseLayout from 'components/layouts/DatabaseLayout/DatabaseLayout' diff --git a/apps/studio/pages/project/[ref]/database/triggers.tsx b/apps/studio/pages/project/[ref]/database/triggers.tsx index 587f409b39dbb..4f90286f184f6 100644 --- a/apps/studio/pages/project/[ref]/database/triggers.tsx +++ b/apps/studio/pages/project/[ref]/database/triggers.tsx @@ -13,7 +13,7 @@ import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold' import { EditorPanel } from 'components/ui/EditorPanel/EditorPanel' import { FormHeader } from 'components/ui/Forms/FormHeader' import NoPermission from 'components/ui/NoPermission' -import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import type { NextPageWithLayout } from 'types' const TriggersPage: NextPageWithLayout = () => { @@ -27,8 +27,10 @@ const TriggersPage: NextPageWithLayout = () => { const [editorPanelOpen, setEditorPanelOpen] = useState(false) const [selectedTriggerForEditor, setSelectedTriggerForEditor] = useState() - const canReadTriggers = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_READ, 'triggers') - const isPermissionsLoaded = usePermissionsLoaded() + const { can: canReadTriggers, isSuccess: isPermissionsLoaded } = useAsyncCheckProjectPermissions( + PermissionAction.TENANT_SQL_ADMIN_READ, + 'triggers' + ) const createTrigger = () => { if (isInlineEditorEnabled) { diff --git a/apps/studio/pages/project/[ref]/functions/[functionSlug]/code.tsx b/apps/studio/pages/project/[ref]/functions/[functionSlug]/code.tsx index b444c84d4a369..be79cc4262440 100644 --- a/apps/studio/pages/project/[ref]/functions/[functionSlug]/code.tsx +++ b/apps/studio/pages/project/[ref]/functions/[functionSlug]/code.tsx @@ -14,8 +14,7 @@ import { useEdgeFunctionBodyQuery } from 'data/edge-functions/edge-function-body import { useEdgeFunctionQuery } from 'data/edge-functions/edge-function-query' import { useEdgeFunctionDeployMutation } from 'data/edge-functions/edge-functions-deploy-mutation' import { useSendEventMutation } from 'data/telemetry/send-event-mutation' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' -import { useOrgAiOptInLevel } from 'hooks/misc/useOrgOptedIntoAi' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { BASE_PATH } from 'lib/constants' @@ -29,7 +28,10 @@ const CodePage = () => { const { mutate: sendEvent } = useSendEventMutation() const [showDeployWarning, setShowDeployWarning] = useState(false) - const canDeployFunction = useCheckPermissions(PermissionAction.FUNCTIONS_WRITE, '*') + const { can: canDeployFunction } = useAsyncCheckProjectPermissions( + PermissionAction.FUNCTIONS_WRITE, + '*' + ) const { data: selectedFunction } = useEdgeFunctionQuery({ projectRef: ref, slug: functionSlug }) const { diff --git a/apps/studio/pages/project/[ref]/realtime/inspector.tsx b/apps/studio/pages/project/[ref]/realtime/inspector.tsx index 12c7968597fa6..5f8b7314cff6a 100644 --- a/apps/studio/pages/project/[ref]/realtime/inspector.tsx +++ b/apps/studio/pages/project/[ref]/realtime/inspector.tsx @@ -1,19 +1,10 @@ -import { PermissionAction } from '@supabase/shared-types/out/constants' import type { NextPageWithLayout } from 'types' import { RealtimeInspector } from 'components/interfaces/Realtime/Inspector' -import RealtimeLayout from 'components/layouts/RealtimeLayout/RealtimeLayout' import DefaultLayout from 'components/layouts/DefaultLayout' -import NoPermission from 'components/ui/NoPermission' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import RealtimeLayout from 'components/layouts/RealtimeLayout/RealtimeLayout' export const InspectorPage: NextPageWithLayout = () => { - const canReadAPIKeys = useCheckPermissions(PermissionAction.READ, 'service_api_keys') - - if (!canReadAPIKeys) { - return - } - return } diff --git a/apps/studio/pages/project/[ref]/reports/database.tsx b/apps/studio/pages/project/[ref]/reports/database.tsx index a598bb3712bdb..dab6b263b61b7 100644 --- a/apps/studio/pages/project/[ref]/reports/database.tsx +++ b/apps/studio/pages/project/[ref]/reports/database.tsx @@ -1,16 +1,16 @@ import { PermissionAction } from '@supabase/shared-types/out/constants' import { useQueryClient } from '@tanstack/react-query' -import { useParams } from 'common' import dayjs from 'dayjs' import { ArrowRight, ExternalLink, RefreshCw } from 'lucide-react' import Link from 'next/link' import { useEffect, useState } from 'react' import { toast } from 'sonner' -import { AlertDescription_Shadcn_, Alert_Shadcn_, Button } from 'ui' +import { useParams } from 'common' import ReportChart from 'components/interfaces/Reports/ReportChart' import ReportHeader from 'components/interfaces/Reports/ReportHeader' import ReportPadding from 'components/interfaces/Reports/ReportPadding' +import { REPORT_DATERANGE_HELPER_LABELS } from 'components/interfaces/Reports/Reports.constants' import ReportStickyNav from 'components/interfaces/Reports/ReportStickyNav' import ReportWidget from 'components/interfaces/Reports/ReportWidget' import DiskSizeConfigurationModal from 'components/interfaces/Settings/Database/DiskSizeConfigurationModal' @@ -21,26 +21,24 @@ import ReportsLayout from 'components/layouts/ReportsLayout/ReportsLayout' import Table from 'components/to-be-cleaned/Table' import { ButtonTooltip } from 'components/ui/ButtonTooltip' import ChartHandler from 'components/ui/Charts/ChartHandler' +import type { MultiAttribute } from 'components/ui/Charts/ComposedChart.utils' import ComposedChartHandler from 'components/ui/Charts/ComposedChartHandler' import GrafanaPromoBanner from 'components/ui/GrafanaPromoBanner' import Panel from 'components/ui/Panel' -import { useDatabaseSelectorStateSnapshot } from 'state/database-selector' - -import { REPORT_DATERANGE_HELPER_LABELS } from 'components/interfaces/Reports/Reports.constants' import { analyticsKeys } from 'data/analytics/keys' import { useProjectDiskResizeMutation } from 'data/config/project-disk-resize-mutation' import { useDatabaseSizeQuery } from 'data/database/database-size-query' import { getReportAttributes, getReportAttributesV2 } from 'data/reports/database-charts' import { useDatabaseReport } from 'data/reports/database-report-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useReportDateRange } from 'hooks/misc/useReportDateRange' import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization' +import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { useFlag } from 'hooks/ui/useFlag' import { formatBytes } from 'lib/helpers' - -import type { MultiAttribute } from 'components/ui/Charts/ComposedChart.utils' -import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' +import { useDatabaseSelectorStateSnapshot } from 'state/database-selector' import type { NextPageWithLayout } from 'types' +import { AlertDescription_Shadcn_, Alert_Shadcn_, Button } from 'ui' const DatabaseReport: NextPageWithLayout = () => { return ( @@ -99,11 +97,15 @@ const DatabaseUsage = () => { const databaseSizeBytes = databaseSizeData ?? 0 const currentDiskSize = project?.volumeSizeGb ?? 0 - const canUpdateDiskSizeConfig = useCheckPermissions(PermissionAction.UPDATE, 'projects', { - resource: { - project_id: project?.id, - }, - }) + const { can: canUpdateDiskSizeConfig } = useAsyncCheckProjectPermissions( + PermissionAction.UPDATE, + 'projects', + { + resource: { + project_id: project?.id, + }, + } + ) const REPORT_ATTRIBUTES = getReportAttributes(org!, project!) const REPORT_ATTRIBUTES_V2 = getReportAttributesV2(org!, project!) diff --git a/apps/studio/pages/project/[ref]/reports/index.tsx b/apps/studio/pages/project/[ref]/reports/index.tsx index c063658e31f31..ff2cc6e12e676 100644 --- a/apps/studio/pages/project/[ref]/reports/index.tsx +++ b/apps/studio/pages/project/[ref]/reports/index.tsx @@ -4,14 +4,14 @@ import { useState } from 'react' import { useParams } from 'common' import { CreateReportModal } from 'components/interfaces/Reports/CreateReportModal' +import DefaultLayout from 'components/layouts/DefaultLayout' import ReportsLayout from 'components/layouts/ReportsLayout/ReportsLayout' import ProductEmptyState from 'components/to-be-cleaned/ProductEmptyState' import { Loading } from 'components/ui/Loading' import { useContentQuery } from 'data/content/content-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useProfile } from 'lib/profile' import type { NextPageWithLayout } from 'types' -import DefaultLayout from 'components/layouts/DefaultLayout' export const UserReportPage: NextPageWithLayout = () => { const router = useRouter() @@ -36,10 +36,14 @@ export const UserReportPage: NextPageWithLayout = () => { } ) - const canCreateReport = useCheckPermissions(PermissionAction.CREATE, 'user_content', { - resource: { type: 'report', owner_id: profile?.id }, - subject: { id: profile?.id }, - }) + const { can: canCreateReport } = useAsyncCheckProjectPermissions( + PermissionAction.CREATE, + 'user_content', + { + resource: { type: 'report', owner_id: profile?.id }, + subject: { id: profile?.id }, + } + ) return (
diff --git a/apps/studio/pages/project/[ref]/settings/jwt/signing-keys.tsx b/apps/studio/pages/project/[ref]/settings/jwt/signing-keys.tsx index 406f8d9ae011a..72f40dd8e683d 100644 --- a/apps/studio/pages/project/[ref]/settings/jwt/signing-keys.tsx +++ b/apps/studio/pages/project/[ref]/settings/jwt/signing-keys.tsx @@ -1,16 +1,19 @@ import { PermissionAction } from '@supabase/shared-types/out/constants' + import JWTSecretKeysTable from 'components/interfaces/JwtSecrets/jwt-secret-keys-table' import DefaultLayout from 'components/layouts/DefaultLayout' import JWTKeysLayout from 'components/layouts/JWTKeys/JWTKeysLayout' import SettingsLayout from 'components/layouts/ProjectSettingsLayout/SettingsLayout' import NoPermission from 'components/ui/NoPermission' import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader' -import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import type { NextPageWithLayout } from 'types' const JWTSigningKeysPage: NextPageWithLayout = () => { - const isPermissionsLoaded = usePermissionsLoaded() - const canReadAPIKeys = useCheckPermissions(PermissionAction.READ, 'auth_signing_keys') + const { can: canReadAPIKeys, isSuccess: isPermissionsLoaded } = useAsyncCheckProjectPermissions( + PermissionAction.READ, + 'auth_signing_keys' + ) return ( <> diff --git a/apps/studio/pages/project/[ref]/settings/log-drains.tsx b/apps/studio/pages/project/[ref]/settings/log-drains.tsx index e84dcaea91f22..cdd982e072b9e 100644 --- a/apps/studio/pages/project/[ref]/settings/log-drains.tsx +++ b/apps/studio/pages/project/[ref]/settings/log-drains.tsx @@ -6,6 +6,7 @@ import { useParams } from 'common' import { LogDrainDestinationSheetForm } from 'components/interfaces/LogDrains/LogDrainDestinationSheetForm' import { LogDrains } from 'components/interfaces/LogDrains/LogDrains' import { LogDrainType } from 'components/interfaces/LogDrains/LogDrains.constants' +import DefaultLayout from 'components/layouts/DefaultLayout' import SettingsLayout from 'components/layouts/ProjectSettingsLayout/SettingsLayout' import { ScaffoldContainer, @@ -17,14 +18,15 @@ import { DocsButton } from 'components/ui/DocsButton' import { useCreateLogDrainMutation } from 'data/log-drains/create-log-drain-mutation' import { LogDrainData, useLogDrainsQuery } from 'data/log-drains/log-drains-query' import { useUpdateLogDrainMutation } from 'data/log-drains/update-log-drain-mutation' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' import { useCurrentOrgPlan } from 'hooks/misc/useCurrentOrgPlan' import type { NextPageWithLayout } from 'types' import { Alert_Shadcn_, Button } from 'ui' -import DefaultLayout from 'components/layouts/DefaultLayout' +import { GenericSkeletonLoader } from 'ui-patterns' const LogDrainsSettings: NextPageWithLayout = () => { - const canManageLogDrains = useCheckPermissions(PermissionAction.ANALYTICS_ADMIN_WRITE, 'logflare') + const { can: canManageLogDrains, isLoading: isLoadingPermissions } = + useAsyncCheckProjectPermissions(PermissionAction.ANALYTICS_ADMIN_WRITE, 'logflare') const [open, setOpen] = useState(false) const { ref } = useParams() as { ref: string } @@ -35,12 +37,7 @@ const LogDrainsSettings: NextPageWithLayout = () => { const logDrainsEnabled = !planLoading && (plan?.id === 'team' || plan?.id === 'enterprise') - const { data: logDrains } = useLogDrainsQuery( - { ref }, - { - enabled: logDrainsEnabled, - } - ) + const { data: logDrains } = useLogDrainsQuery({ ref }, { enabled: logDrainsEnabled }) const { mutate: createLogDrain, isLoading: createLoading } = useCreateLogDrainMutation({ onSuccess: () => { @@ -144,12 +141,15 @@ const LogDrainsSettings: NextPageWithLayout = () => { } }} /> - {canManageLogDrains ? ( - - ) : ( + + {isLoadingPermissions ? ( + + ) : !canManageLogDrains ? ( You do not have permission to manage log drains + ) : ( + )} From c32c74e34c825e30ae3f32b3043416bdd4731219 Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Tue, 12 Aug 2025 21:18:24 +0800 Subject: [PATCH 3/7] fix: diff all schemas on branch merge (#37754) * fix: diff all schemas on branch merge * chore: remove branching limitation on schema and extensions * chore: remove limitation from blog post * chore: remove limitation from docs --- apps/docs/content/guides/deployment/branching/dashboard.mdx | 2 -- .../interfaces/App/FeaturePreview/Branching2Preview.tsx | 4 ---- apps/studio/data/branches/branch-merge-mutation.ts | 2 +- apps/www/_blog/2025-07-16-branching-2-0.mdx | 2 -- 4 files changed, 1 insertion(+), 9 deletions(-) diff --git a/apps/docs/content/guides/deployment/branching/dashboard.mdx b/apps/docs/content/guides/deployment/branching/dashboard.mdx index 2d938165736cd..a7577014d5a8d 100644 --- a/apps/docs/content/guides/deployment/branching/dashboard.mdx +++ b/apps/docs/content/guides/deployment/branching/dashboard.mdx @@ -58,8 +58,6 @@ When reviewing a merge request you may see a notice at the top of the page askin There are a few limitations you should be aware of before deciding to use branching without git. - Custom roles created through the dashboard are not captured on branch creation -- Only public schema changes are supported right now -- Extensions are not included in the diff process - Branches can only be merged to main; merging between preview branches is not supported - If your branch is out of date, you can pull in latest changes from main, but keep in mind that all functions will be overwritten - Deleting functions must be done manually on main branch diff --git a/apps/studio/components/interfaces/App/FeaturePreview/Branching2Preview.tsx b/apps/studio/components/interfaces/App/FeaturePreview/Branching2Preview.tsx index 6aba6698b34a2..9bf5f6d30c1d5 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/Branching2Preview.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/Branching2Preview.tsx @@ -25,10 +25,6 @@ export const Branching2Preview = () => {

Limitations:

  • Custom roles created through the dashboard are not captured on branch creation.
  • -
  • - Only public schema changes are supported right now. -
  • -
  • Extensions are not included in the diff process
  • Branches can only be merged to main; merging between preview branches is not supported. diff --git a/apps/studio/data/branches/branch-merge-mutation.ts b/apps/studio/data/branches/branch-merge-mutation.ts index bceacc382237f..4d2fe1effc1f7 100644 --- a/apps/studio/data/branches/branch-merge-mutation.ts +++ b/apps/studio/data/branches/branch-merge-mutation.ts @@ -21,7 +21,7 @@ export async function mergeBranch({ migration_version, }: BranchMergeVariables) { // Step 1: Get the diff output from the branch - const diffContent = await getBranchDiff({ branchId: id, includedSchemas: 'public' }) + const diffContent = await getBranchDiff({ branchId: id }) let migrationCreated = false diff --git a/apps/www/_blog/2025-07-16-branching-2-0.mdx b/apps/www/_blog/2025-07-16-branching-2-0.mdx index 3d1342e0d0d42..a8e88087eb64b 100644 --- a/apps/www/_blog/2025-07-16-branching-2-0.mdx +++ b/apps/www/_blog/2025-07-16-branching-2-0.mdx @@ -108,8 +108,6 @@ When ready, click the merge button and watch your changes be deployed to product There are a few limitations you should be aware of before deciding to use branching without git. - Custom roles created through the dashboard are not captured on branch creation. -- Only public schema changes are supported right now. -- Extensions are not included in the diff process - Branches can only be merged to main; merging between preview branches is not supported. - If your branch is out of date, you can pull in latest changes from main, but keep in mind that all functions will be overwritten. - Deleting functions must be done manually on main branch. From 4b2705f0ba7c23a1acd08079508db60e09f77a42 Mon Sep 17 00:00:00 2001 From: Oleg Polin <140200108+olegpolin@users.noreply.github.com> Date: Tue, 12 Aug 2025 10:38:06 -0400 Subject: [PATCH 4/7] fix(docs): update SvelteKit tutorial to use Svelte 5 syntax (#31229) * docs: Update SvelteKit auth tutorial project creation syntax (#31114) * docs: Update link to SvelteKit docs (#31114) * Update +layout.svelte to Svelte 5 syntax (#31114) * Update +page.svelte to use Svelte 5 syntax (#31114) * Update account +page.svelte to use Svelte 5 syntax (#31114) * Update account Avatar.svelte to use Svelte 5 syntax (#31114) * Update SvelteKit example to Svelte 5 syntax (#31114) * docs: Update npm dependencies (#31114) * Start review * Finish review * Update code for SvelteKit 5 * Convert to codesamples --------- Co-authored-by: Chris Chinchilla Co-authored-by: Chris Chinchilla --- .../tutorials/with-sveltekit.mdx | 705 +------ .../package-lock.json | 1702 ++++++++--------- .../sveltekit-user-management/package.json | 14 +- .../src/routes/+layout.svelte | 8 +- .../src/routes/+page.svelte | 9 +- .../src/routes/account/+page.svelte | 15 +- .../src/routes/account/Avatar.svelte | 29 +- .../src/routes/auth/error/+page.svelte | 1 + package.json | 17 +- 9 files changed, 912 insertions(+), 1588 deletions(-) create mode 100644 examples/user-management/sveltekit-user-management/src/routes/auth/error/+page.svelte diff --git a/apps/docs/content/guides/getting-started/tutorials/with-sveltekit.mdx b/apps/docs/content/guides/getting-started/tutorials/with-sveltekit.mdx index 1b114f50a60be..43def489bf8d5 100644 --- a/apps/docs/content/guides/getting-started/tutorials/with-sveltekit.mdx +++ b/apps/docs/content/guides/getting-started/tutorials/with-sveltekit.mdx @@ -17,14 +17,14 @@ If you get stuck while working through this guide, refer to the [full example on ## Building the app -Let's start building the Svelte app from scratch. +Start building the Svelte app from scratch. ### Initialize a Svelte app -We can use the [SvelteKit Skeleton Project](https://kit.svelte.dev/docs) to initialize an app called `supabase-sveltekit` (for this tutorial we will be using TypeScript): +Use the [SvelteKit Skeleton Project](https://svelte.dev/docs/kit) to initialize an app called `supabase-sveltekit` (for this tutorial, select "SvelteKit minimal" and use TypeScript): ```bash -npm create svelte@latest supabase-sveltekit +npx sv create supabase-sveltekit cd supabase-sveltekit npm install ``` @@ -35,8 +35,8 @@ Then install the Supabase client library: [supabase-js](https://github.com/supab npm install @supabase/supabase-js ``` -And finally we want to save the environment variables in a `.env`. -All we need are the `SUPABASE_URL` and the `SUPABASE_KEY` key that you copied [earlier](#get-the-api-keys). +And finally, save the environment variables in a `.env` file. +All you need are the `PUBLIC_SUPABASE_URL` and the `PUBLIC_SUPABASE_ANON_KEY` key that you copied [earlier](#get-the-api-keys). <$CodeTabs> @@ -47,108 +47,46 @@ PUBLIC_SUPABASE_ANON_KEY="YOUR_SUPABASE_KEY" -Optionally, add `src/styles.css` with the [CSS from the example](https://raw.githubusercontent.com/supabase/supabase/master/examples/user-management/sveltekit-user-management/src/styles.css). +### App styling (optional) + +An optional step is to update the CSS file `src/styles.css` to make the app look nice. +You can find the full contents of this file [in the example repository](https://raw.githubusercontent.com/supabase/supabase/master/examples/user-management/sveltekit-user-management/src/styles.css). ### Creating a Supabase client for SSR -The `ssr` package configures Supabase to use Cookies, which is required for server-side languages and frameworks. +The `ssr` package configures Supabase to use Cookies, which are required for server-side languages and frameworks. -Install the Supabase packages: +Install the SSR package: ```bash -npm install @supabase/ssr @supabase/supabase-js +npm install @supabase/ssr ``` -Creating a Supabase client with the `ssr` package automatically configures it to use Cookies. This means your user's session is available throughout the entire SvelteKit stack - page, layout, server, hooks. +Creating a Supabase client with the `ssr` package automatically configures it to use Cookies. This means the user's session is available throughout the entire SvelteKit stack - page, layout, server, and hooks. -Add the code below to your `src/hooks.server.ts` to initialize the client on the server: +Add the code below to a `src/hooks.server.ts` file to initialize the client on the server: <$CodeTabs> -```ts name=src/hooks.server.ts -// src/hooks.server.ts -import { PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY } from '$env/static/public' -import { createServerClient } from '@supabase/ssr' -import type { Handle } from '@sveltejs/kit' - -export const handle: Handle = async ({ event, resolve }) => { - event.locals.supabase = createServerClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, { - cookies: { - getAll: () => event.cookies.getAll(), - /** - * SvelteKit's cookies API requires `path` to be explicitly set in - * the cookie options. Setting `path` to `/` replicates previous/ - * standard behavior. - */ - setAll: (cookiesToSet) => { - cookiesToSet.forEach(({ name, value, options }) => { - event.cookies.set(name, value, { ...options, path: '/' }) - }) - }, - }, - }) - - /** - * Unlike `supabase.auth.getSession()`, which returns the session _without_ - * validating the JWT, this function also calls `getUser()` to validate the - * JWT before returning the session. - */ - event.locals.safeGetSession = async () => { - const { - data: { session }, - } = await event.locals.supabase.auth.getSession() - if (!session) { - return { session: null, user: null } - } - - const { - data: { user }, - error, - } = await event.locals.supabase.auth.getUser() - if (error) { - // JWT validation has failed - return { session: null, user: null } - } - - return { session, user } - } - - return resolve(event, { - filterSerializedResponseHeaders(name) { - return name === 'content-range' || name === 'x-supabase-api-version' - }, - }) -} -``` +<$CodeSample +path="/user-management/sveltekit-user-management/src/hooks.server.ts" +lines={[[1, -1]]} +meta="name=src/hooks.server.ts" +/> <$Partial path="get_session_warning.mdx" /> - -If you are using TypeScript the compiler might complain about `event.locals.supabase` and `event.locals.safeGetSession`, this can be fixed by updating your `src/app.d.ts` with the content below: +{/* TODO: Change when adding JS autoconversion */} +As this tutorial uses TypeScript the compiler complains about `event.locals.supabase` and `event.locals.safeGetSession`, you can fix this by updating the `src/app.d.ts` with the content below: <$CodeTabs> -```ts name=src/app.d.ts -// src/app.d.ts - -import { SupabaseClient, Session } from '@supabase/supabase-js' - -declare global { - namespace App { - interface Locals { - supabase: SupabaseClient - safeGetSession(): Promise<{ session: Session | null; user: User | null }> - } - interface PageData { - session: Session | null - user: User | null - } - // interface Error {} - // interface Platform {} - } -} -``` +<$CodeSample +path="/user-management/sveltekit-user-management/src/app.d.ts" +lines={[[1, -1]]} +meta="name=src/app.d.ts" +/> @@ -156,26 +94,17 @@ Create a new `src/routes/+layout.server.ts` file to handle the session on the se <$CodeTabs> -```ts name=src/routes/+layout.server.ts -// src/routes/+layout.server.ts -import type { LayoutServerLoad } from './$types' - -export const load: LayoutServerLoad = async ({ locals: { safeGetSession }, cookies }) => { - const { session, user } = await safeGetSession() - - return { - session, - user, - cookies: cookies.getAll(), - } -} -``` +<$CodeSample +path="/user-management/sveltekit-user-management/src/routes/+layout.server.ts" +lines={[[1, -1]]} +meta="name=src/routes/+layout.server.ts" +/> -Start your dev server (`npm run dev`) in order to generate the `./$types` files we are referencing in our project. +Start the dev server (`npm run dev`) to generate the `./$types` files we are referencing in our project. @@ -183,202 +112,49 @@ Create a new `src/routes/+layout.ts` file to handle the session and the `supabas <$CodeTabs> -```ts name=src/routes/+layout.ts -// src/routes/+layout.ts -import { createBrowserClient, createServerClient, isBrowser } from '@supabase/ssr' -import { PUBLIC_SUPABASE_ANON_KEY, PUBLIC_SUPABASE_URL } from '$env/static/public' -import type { LayoutLoad } from './$types' - -export const load: LayoutLoad = async ({ fetch, data, depends }) => { - depends('supabase:auth') - - const supabase = isBrowser() - ? createBrowserClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, { - global: { - fetch, - }, - }) - : createServerClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, { - global: { - fetch, - }, - cookies: { - getAll() { - return data.cookies - }, - }, - }) - - /** - * It's fine to use `getSession` here, because on the client, `getSession` is - * safe, and on the server, it reads `session` from the `LayoutData`, which - * safely checked the session using `safeGetSession`. - */ - const { - data: { session }, - } = await supabase.auth.getSession() - - return { supabase, session } -} -``` +<$CodeSample +path="/user-management/sveltekit-user-management/src/routes/+layout.ts" +lines={[[1, -1]]} +meta="name=src/routes/+layout.ts" +/> -Update your `src/routes/+layout.svelte`: +Create `src/routes/+layout.svelte`: <$CodeTabs> -```svelte name=src/routes/+layout.svelte - - - - - User Management - - -
    - -
    -``` +<$CodeSample +path="/user-management/sveltekit-user-management/src/routes/+layout.svelte" +lines={[[1, -1]]} +meta="name=src/routes/+layout.svelte" +/> ## Set up a login page -Create a magic link login/signup page for your application: +Create a magic link login/signup page for your application by updating the `routes/+page.svelte` file: <$CodeTabs> -```svelte name=src/routes/+page.svelte - - - - - User Management - - -
    -
    -

    Supabase + SvelteKit

    -

    Sign in via magic link with your email below

    - {#if form?.message !== undefined} -
    - {form?.message} -
    - {/if} -
    - - -
    - {#if form?.errors?.email} - - {form?.errors?.email} - - {/if} -
    - -
    -
    - -``` +<$CodeSample +path="/user-management/sveltekit-user-management/src/routes/+page.svelte" +lines={[[1, -1]]} +meta="name=src/routes/+page.svelte" +/> -Create a `src/routes/+page.server.ts` file that will handle our magic link form when submitted. +Create a `src/routes/+page.server.ts` file that handles the magic link form when submitted. <$CodeTabs> -```ts name=src/routes/+page.server.ts -// src/routes/+page.server.ts -import { fail, redirect } from '@sveltejs/kit' -import type { Actions, PageServerLoad } from './$types' - -export const load: PageServerLoad = async ({ url, locals: { safeGetSession } }) => { - const { session } = await safeGetSession() - - // if the user is already logged in return them to the account page - if (session) { - redirect(303, '/account') - } - - return { url: url.origin } -} - -export const actions: Actions = { - default: async (event) => { - const { - url, - request, - locals: { supabase }, - } = event - const formData = await request.formData() - const email = formData.get('email') as string - const validEmail = /^[\w-\.+]+@([\w-]+\.)+[\w-]{2,8}$/.test(email) - - if (!validEmail) { - return fail(400, { errors: { email: 'Please enter a valid email address' }, email }) - } - - const { error } = await supabase.auth.signInWithOtp({ email }) - - if (error) { - return fail(400, { - success: false, - email, - message: `There was an issue, Please contact support.`, - }) - } - - return { - success: true, - message: 'Please check your email for a magic link to log into the website.', - } - }, -} -``` +<$CodeSample +path="/user-management/sveltekit-user-management/src/routes/+page.server.ts" +lines={[[1, -1]]} +meta="name=src/routes/+page.server.ts" +/> @@ -388,239 +164,77 @@ Change the email template to support a server-side authentication flow. Before we proceed, let's change the email template to support sending a token hash: -- Go to the [Auth templates](/dashboard/project/_/auth/templates) page in your dashboard. -- Select `Confirm signup` template. +- Go to the [**Auth** > **Emails**](/dashboard/project/_/auth/templates) page in the project dashboard. +- Select the **Confirm signup** template. - Change `{{ .ConfirmationURL }}` to `{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=email`. -- Repeat the previous step for `Magic link` template. +- Repeat the previous step for **Magic link** template. -Did you know? You could also customize emails sent out to new users, including the email's looks, content, and query parameters. Check out the [settings of your project](/dashboard/project/_/auth/templates). +**Did you know?** You can also customize emails sent out to new users, including the email's looks, content, and query parameters. Check out the [settings of your project](/dashboard/project/_/auth/templates). ### Confirmation endpoint -As we are working in a server-side rendering (SSR) environment, it is necessary to create a server endpoint responsible for exchanging the `token_hash` for a session. +As this is a server-side rendering (SSR) environment, you need to create a server endpoint responsible for exchanging the `token_hash` for a session. -In the following code snippet, we perform the following steps: +The following code snippet performs the following steps: -- Retrieve the `token_hash` sent back from the Supabase Auth server using the `token_hash` query parameter. -- Exchange this `token_hash` for a session, which we store in storage (in this case, cookies). -- Finally, the user is redirected to the `account` page or the `error` page. +- Retrieves the `token_hash` sent back from the Supabase Auth server using the `token_hash` query parameter. +- Exchanges this `token_hash` for a session, which you store in storage (in this case, cookies). +- Finally, redirect the user to the `account` page or the `error` page. <$CodeTabs> -```ts name=src/routes/auth/confirm/+server.ts -// src/routes/auth/confirm/+server.ts -import type { EmailOtpType } from '@supabase/supabase-js' -import { redirect } from '@sveltejs/kit' - -import type { RequestHandler } from './$types' - -export const GET: RequestHandler = async ({ url, locals: { supabase } }) => { - const token_hash = url.searchParams.get('token_hash') - const type = url.searchParams.get('type') as EmailOtpType | null - const next = url.searchParams.get('next') ?? '/account' - - /** - * Clean up the redirect URL by deleting the Auth flow parameters. - * - * `next` is preserved for now, because it's needed in the error case. - */ - const redirectTo = new URL(url) - redirectTo.pathname = next - redirectTo.searchParams.delete('token_hash') - redirectTo.searchParams.delete('type') - - if (token_hash && type) { - const { error } = await supabase.auth.verifyOtp({ type, token_hash }) - if (!error) { - redirectTo.searchParams.delete('next') - redirect(303, redirectTo) - } - } - - redirectTo.pathname = '/auth/error' - redirect(303, redirectTo) -} -``` +<$CodeSample +path="/user-management/sveltekit-user-management/src/routes/auth/confirm/+server.ts" +lines={[[1, -1]]} +meta="name=src/routes/auth/confirm/+server.ts" +/> ### Authentication error page -If there is an error with confirming the token you will be redirect to this error page. +If there is an error with confirming the token, redirect the user to an error page. <$CodeTabs> - -```svelte name=src/routes/auth/error/+page.svelte -

    Login error

    -``` +<$CodeSample +path="/user-management/sveltekit-user-management/src/routes/auth/error/+page.svelte" +lines={[[1, -1]]} +meta="name=src/routes/auth/error/+page.svelte" +/> ### Account page -After a user is signed in, they need to be able to edit their profile details and manage their account. +After a user signs in, they need to be able to edit their profile details page. Create a new `src/routes/account/+page.svelte` file with the content below. <$CodeTabs> -```svelte name=src/routes/account/+page.svelte - - - -
    -
    -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - -
    - - -
    -
    - -
    - -
    -``` +<$CodeSample +path="/user-management/sveltekit-user-management/src/routes/account/+page.svelte" +lines={[[1, 3],[6,12],[15,38],[47,-1]]} +meta="name=src/routes/account/+page.svelte" +/> -Now create the associated `src/routes/account/+page.server.ts` file that will handle loading our data from the server through the `load` function -and handle all our form actions through the `actions` object. - -```ts name=src/routes/account/+page.server.ts -import { fail, redirect } from '@sveltejs/kit' -import type { Actions, PageServerLoad } from './$types' - -export const load: PageServerLoad = async ({ locals: { supabase, safeGetSession } }) => { - const { session } = await safeGetSession() - - if (!session) { - redirect(303, '/') - } - - const { data: profile } = await supabase - .from('profiles') - .select(`username, full_name, website, avatar_url`) - .eq('id', session.user.id) - .single() - - return { session, profile } -} - -export const actions: Actions = { - update: async ({ request, locals: { supabase, safeGetSession } }) => { - const formData = await request.formData() - const fullName = formData.get('fullName') as string - const username = formData.get('username') as string - const website = formData.get('website') as string - const avatarUrl = formData.get('avatarUrl') as string - - const { session } = await safeGetSession() - - const { error } = await supabase.from('profiles').upsert({ - id: session?.user.id, - full_name: fullName, - username, - website, - avatar_url: avatarUrl, - updated_at: new Date(), - }) - - if (error) { - return fail(500, { - fullName, - username, - website, - avatarUrl, - }) - } - - return { - fullName, - username, - website, - avatarUrl, - } - }, - signout: async ({ locals: { supabase, safeGetSession } }) => { - const { session } = await safeGetSession() - if (session) { - await supabase.auth.signOut() - redirect(303, '/') - } - }, -} -``` +Now, create the associated `src/routes/account/+page.server.ts` file that handles loading data from the server through the `load` function +and handle all form actions through the `actions` object. + +<$CodeSample +path="/user-management/sveltekit-user-management/src/routes/+page.server.ts" +lines={[[1, -1]]} +meta="name=src/routes/+page.server.ts" +/> ### Launch! -Now that we have all the pages in place, run this in a terminal window: +With all the pages in place, run this command in a terminal: ```bash npm run dev @@ -636,144 +250,29 @@ Every Supabase project is configured with [Storage](/docs/guides/storage) for ma ### Create an upload widget -Let's create an avatar for the user so that they can upload a profile photo. We can start by creating a new component called `Avatar.svelte` in the `src/routes/account` directory: +Create an avatar for the user so that they can upload a profile photo. Start by creating a new component called `Avatar.svelte` in the `src/routes/account` directory: <$CodeTabs> -```svelte name=src/routes/account/Avatar.svelte - - - -
    - {#if avatarUrl} - {avatarUrl - {:else} -
    - {/if} - - -
    - - -
    -
    -``` +<$CodeSample +path="/user-management/sveltekit-user-management/src/routes/account/Avatar.svelte" +lines={[[1, -1]]} +meta="name=src/routes/account/Avatar.svelte" +/> ### Add the new widget -And then we can add the widget to the Account page: +Add the widget to the Account page: <$CodeTabs> -```svelte name=src/routes/account/+page.svelte - - - -
    -
    - - { - profileForm.requestSubmit(); - }} - /> - - - -
    -``` +<$CodeSample +path="/user-management/sveltekit-user-management/src/routes/account/+page.svelte" +lines={[[1, 1], [4,4], [31,31],[39,46],[82,82]]} +meta="name=src/routes/account/+page.svelte" +/> diff --git a/examples/user-management/sveltekit-user-management/package-lock.json b/examples/user-management/sveltekit-user-management/package-lock.json index 344b536aacdcd..62cbfc51c764c 100644 --- a/examples/user-management/sveltekit-user-management/package-lock.json +++ b/examples/user-management/sveltekit-user-management/package-lock.json @@ -10,18 +10,18 @@ "dependencies": { "@supabase/auth-ui-shared": "^0.1.8", "@supabase/auth-ui-svelte": "^0.2.9", - "@supabase/ssr": "^0.4.0", + "@supabase/ssr": "^0.6.1", "@supabase/supabase-js": "^2.44.2" }, "devDependencies": { - "@sveltejs/adapter-auto": "^3.2.2", - "@sveltejs/kit": "^2.5.18", - "@sveltejs/vite-plugin-svelte": "^3.1.1", - "svelte": "^4.2.18", - "svelte-check": "^3.8.4", + "@sveltejs/adapter-auto": "^6.0.1", + "@sveltejs/kit": "^2.5.27", + "@sveltejs/vite-plugin-svelte": "^6.1.0", + "svelte": "^5.14.4", + "svelte-check": "^4.1.1", "tslib": "^2.6.3", "typescript": "^5.5.3", - "vite": "^5.3.3" + "vite": "^7.0.5" } }, "node_modules/@ampproject/remapping": { @@ -29,6 +29,7 @@ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -38,385 +39,456 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz", + "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz", + "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz", + "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz", + "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz", + "integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz", + "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz", + "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz", + "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz", + "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz", + "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz", + "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz", + "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==", "cpu": [ "loong64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz", + "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==", "cpu": [ "mips64el" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz", + "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz", + "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz", + "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz", + "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz", + "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz", + "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz", + "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz", + "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz", + "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz", + "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz", + "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz", + "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz", + "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -424,230 +496,311 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@polka/url": { - "version": "1.0.0-next.25", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", - "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", - "dev": true + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.2.tgz", - "integrity": "sha512-ahxSgCkAEk+P/AVO0vYr7DxOD3CwAQrT0Go9BJyGQ9Ef0QxVOfjDZMiF4Y2s3mLyPrjonchIMH/tbWHucJMykQ==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.45.1.tgz", + "integrity": "sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.2.tgz", - "integrity": "sha512-lAarIdxZWbFSHFSDao9+I/F5jDaKyCqAPMq5HqnfpBw8dKDiCaaqM0lq5h1pQTLeIqueeay4PieGR5jGZMWprw==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.45.1.tgz", + "integrity": "sha512-ujQ+sMXJkg4LRJaYreaVx7Z/VMgBBd89wGS4qMrdtfUFZ+TSY5Rs9asgjitLwzeIbhwdEhyj29zhst3L1lKsRQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.2.tgz", - "integrity": "sha512-SWsr8zEUk82KSqquIMgZEg2GE5mCSfr9sE/thDROkX6pb3QQWPp8Vw8zOq2GyxZ2t0XoSIUlvHDkrf5Gmf7x3Q==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.45.1.tgz", + "integrity": "sha512-FSncqHvqTm3lC6Y13xncsdOYfxGSLnP+73k815EfNmpewPs+EyM49haPS105Rh4aF5mJKywk9X0ogzLXZzN9lA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.2.tgz", - "integrity": "sha512-o/HAIrQq0jIxJAhgtIvV5FWviYK4WB0WwV91SLUnsliw1lSAoLsmgEEgRWzDguAFeUEUUoIWXiJrPqU7vGiVkA==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.45.1.tgz", + "integrity": "sha512-2/vVn/husP5XI7Fsf/RlhDaQJ7x9zjvC81anIVbr4b/f0xtSmXQTFcGIQ/B1cXIYM6h2nAhJkdMHTnD7OtQ9Og==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.45.1.tgz", + "integrity": "sha512-4g1kaDxQItZsrkVTdYQ0bxu4ZIQ32cotoQbmsAnW1jAE4XCMbcBPDirX5fyUzdhVCKgPcrwWuucI8yrVRBw2+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.45.1.tgz", + "integrity": "sha512-L/6JsfiL74i3uK1Ti2ZFSNsp5NMiM4/kbbGEcOCps99aZx3g8SJMO1/9Y0n/qKlWZfn6sScf98lEOUe2mBvW9A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.2.tgz", - "integrity": "sha512-nwlJ65UY9eGq91cBi6VyDfArUJSKOYt5dJQBq8xyLhvS23qO+4Nr/RreibFHjP6t+5ap2ohZrUJcHv5zk5ju/g==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.45.1.tgz", + "integrity": "sha512-RkdOTu2jK7brlu+ZwjMIZfdV2sSYHK2qR08FUWcIoqJC2eywHbXr0L8T/pONFwkGukQqERDheaGTeedG+rra6Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.45.1.tgz", + "integrity": "sha512-3kJ8pgfBt6CIIr1o+HQA7OZ9mp/zDk3ctekGl9qn/pRBgrRgfwiffaUmqioUGN9hv0OHv2gxmvdKOkARCtRb8Q==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.2.tgz", - "integrity": "sha512-Pg5TxxO2IVlMj79+c/9G0LREC9SY3HM+pfAwX7zj5/cAuwrbfj2Wv9JbMHIdPCfQpYsI4g9mE+2Bw/3aeSs2rQ==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.45.1.tgz", + "integrity": "sha512-k3dOKCfIVixWjG7OXTCOmDfJj3vbdhN0QYEqB+OuGArOChek22hn7Uy5A/gTDNAcCy5v2YcXRJ/Qcnm4/ma1xw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.2.tgz", - "integrity": "sha512-cAOTjGNm84gc6tS02D1EXtG7tDRsVSDTBVXOLbj31DkwfZwgTPYZ6aafSU7rD/4R2a34JOwlF9fQayuTSkoclA==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.45.1.tgz", + "integrity": "sha512-PmI1vxQetnM58ZmDFl9/Uk2lpBBby6B6rF4muJc65uZbxCs0EA7hhKCk2PKlmZKuyVSHAyIw3+/SiuMLxKxWog==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.45.1.tgz", + "integrity": "sha512-9UmI0VzGmNJ28ibHW2GpE2nF0PBQqsyiS4kcJ5vK+wuwGnV5RlqdczVocDSUfGX/Na7/XINRVoUgJyFIgipoRg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.2.tgz", - "integrity": "sha512-4RyT6v1kXb7C0fn6zV33rvaX05P0zHoNzaXI/5oFHklfKm602j+N4mn2YvoezQViRLPnxP8M1NaY4s/5kXO5cw==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.45.1.tgz", + "integrity": "sha512-7nR2KY8oEOUTD3pBAxIBBbZr0U7U+R9HDTPNy+5nVVHDXI4ikYniH1oxQz9VoB5PbBU1CZuDGHkLJkd3zLMWsg==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.2.tgz", - "integrity": "sha512-KNUH6jC/vRGAKSorySTyc/yRYlCwN/5pnMjXylfBniwtJx5O7X17KG/0efj8XM3TZU7raYRXJFFReOzNmL1n1w==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.45.1.tgz", + "integrity": "sha512-nlcl3jgUultKROfZijKjRQLUu9Ma0PeNv/VFHkZiKbXTBQXhpytS8CIj5/NfBeECZtY2FJQubm6ltIxm/ftxpw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.45.1.tgz", + "integrity": "sha512-HJV65KLS51rW0VY6rvZkiieiBnurSzpzore1bMKAhunQiECPuxsROvyeaot/tcK3A3aGnI+qTHqisrpSgQrpgA==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.2.tgz", - "integrity": "sha512-xPV4y73IBEXToNPa3h5lbgXOi/v0NcvKxU0xejiFw6DtIYQqOTMhZ2DN18/HrrP0PmiL3rGtRG9gz1QE8vFKXQ==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.45.1.tgz", + "integrity": "sha512-NITBOCv3Qqc6hhwFt7jLV78VEO/il4YcBzoMGGNxznLgRQf43VQDae0aAzKiBeEPIxnDrACiMgbqjuihx08OOw==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.2.tgz", - "integrity": "sha512-QBhtr07iFGmF9egrPOWyO5wciwgtzKkYPNLVCFZTmr4TWmY0oY2Dm/bmhHjKRwZoGiaKdNcKhFtUMBKvlchH+Q==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.45.1.tgz", + "integrity": "sha512-+E/lYl6qu1zqgPEnTrs4WysQtvc/Sh4fC2nByfFExqgYrqkKWp1tWIbe+ELhixnenSpBbLXNi6vbEEJ8M7fiHw==", "cpu": [ "x64" ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.2.tgz", - "integrity": "sha512-8zfsQRQGH23O6qazZSFY5jP5gt4cFvRuKTpuBsC1ZnSWxV8ZKQpPqOZIUtdfMOugCcBvFGRa1pDC/tkf19EgBw==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.45.1.tgz", + "integrity": "sha512-a6WIAp89p3kpNoYStITT9RbTbTnqarU7D8N8F2CV+4Cl9fwCOZraLVuVFvlpsW0SbIiYtEnhCZBPLoNdRkjQFw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.2.tgz", - "integrity": "sha512-H4s8UjgkPnlChl6JF5empNvFHp77Jx+Wfy2EtmYPe9G22XV+PMuCinZVHurNe8ggtwoaohxARJZbaH/3xjB/FA==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.45.1.tgz", + "integrity": "sha512-T5Bi/NS3fQiJeYdGvRpTAP5P02kqSOpqiopwhj0uaXB6nzs5JVi2XMJb18JUSKhCOX8+UE1UKQufyD6Or48dJg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.2.tgz", - "integrity": "sha512-djqpAjm/i8erWYF0K6UY4kRO3X5+T4TypIqw60Q8MTqSBaQNpNXDhxdjpZ3ikgb+wn99svA7jxcXpiyg9MUsdw==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.45.1.tgz", + "integrity": "sha512-lxV2Pako3ujjuUe9jiU3/s7KSrDfH6IgTSQOnDWr9aJ92YsFd7EurmClK0ly/t8dzMkDtd04g60WX6yl0sGfdw==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.2.tgz", - "integrity": "sha512-teAqzLT0yTYZa8ZP7zhFKEx4cotS8Tkk5XiqNMJhD4CpaWB1BHARE4Qy+RzwnXvSAYv+Q3jAqCVBS+PS+Yee8Q==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.45.1.tgz", + "integrity": "sha512-M/fKi4sasCdM8i0aWJjCSFm2qEnYRR8AMLG2kxp6wD13+tMGA4Z1tVAuHkNRjud5SW2EM3naLuK35w9twvf6aA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -656,12 +809,14 @@ "node_modules/@stitches/core": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@stitches/core/-/core-1.2.8.tgz", - "integrity": "sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg==" + "integrity": "sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg==", + "license": "MIT" }, "node_modules/@supabase/auth-js": { - "version": "2.64.2", - "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.64.2.tgz", - "integrity": "sha512-s+lkHEdGiczDrzXJ1YWt2y3bxRi+qIUnXcgkpLSrId7yjBeaXBFygNjTaoZLG02KNcYwbuZ9qkEIqmj2hF7svw==", + "version": "2.71.1", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.71.1.tgz", + "integrity": "sha512-mMIQHBRc+SKpZFRB2qtupuzulaUhFYupNyxqDj5Jp/LyPvcWvjaJzZzObv6URtL/O6lPxkanASnotGtNpS3H2Q==", + "license": "MIT", "dependencies": { "@supabase/node-fetch": "^2.6.14" } @@ -670,6 +825,7 @@ "version": "0.1.8", "resolved": "https://registry.npmjs.org/@supabase/auth-ui-shared/-/auth-ui-shared-0.1.8.tgz", "integrity": "sha512-ouQ0DjKcEFg+0gZigFIEgu01V3e6riGZPzgVD0MJsCBNsMsiDT74+GgCEIElMUpTGkwSja3xLwdFRFgMNFKcjg==", + "license": "MIT", "peerDependencies": { "@supabase/supabase-js": "^2.21.0" } @@ -691,14 +847,16 @@ "version": "3.59.2", "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.2.tgz", "integrity": "sha512-vzSyuGr3eEoAtT/A6bmajosJZIUWySzY2CzB3w2pgPvnkUjGqlDnsNnA0PMO+mMAhuyMul6C2uuZzY6ELSkzyA==", + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@supabase/functions-js": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.4.1.tgz", - "integrity": "sha512-8sZ2ibwHlf+WkHDUZJUXqqmPvWQ3UHN0W30behOJngVh/qHHekhJLCFbh0AjkE9/FqqXtf9eoVvmYgfCLk5tNA==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.4.5.tgz", + "integrity": "sha512-v5GSqb9zbosquTo6gBwIiq7W9eQ7rE5QazsK/ezNiQXdCbY+bH8D9qEaBIkhVvX4ZRW5rP03gEfw5yw9tiq4EQ==", + "license": "MIT", "dependencies": { "@supabase/node-fetch": "^2.6.14" } @@ -707,6 +865,7 @@ "version": "2.6.15", "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz", "integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==", + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -715,90 +874,101 @@ } }, "node_modules/@supabase/postgrest-js": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.15.7.tgz", - "integrity": "sha512-TJztay5lcnnKuXjIO/X/aaajOsP8qNeW0k3MqIFoOtRolj5MEAIy8rixNakRk3o23eVCdsuP3iMLYPvOOruH6Q==", + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.19.4.tgz", + "integrity": "sha512-O4soKqKtZIW3olqmbXXbKugUtByD2jPa8kL2m2c1oozAO11uCcGrRhkZL0kVxjBLrXHE0mdSkFsMj7jDSfyNpw==", + "license": "MIT", "dependencies": { "@supabase/node-fetch": "^2.6.14" } }, "node_modules/@supabase/realtime-js": { - "version": "2.10.2", - "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.10.2.tgz", - "integrity": "sha512-qyCQaNg90HmJstsvr2aJNxK2zgoKh9ZZA8oqb7UT2LCh3mj9zpa3Iwu167AuyNxsxrUE8eEJ2yH6wLCij4EApA==", + "version": "2.11.15", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.11.15.tgz", + "integrity": "sha512-HQKRnwAqdVqJW/P9TjKVK+/ETpW4yQ8tyDPPtRMKOH4Uh3vQD74vmj353CYs8+YwVBKubeUOOEpI9CT8mT4obw==", + "license": "MIT", "dependencies": { - "@supabase/node-fetch": "^2.6.14", - "@types/phoenix": "^1.5.4", - "@types/ws": "^8.5.10", - "ws": "^8.14.2" + "@supabase/node-fetch": "^2.6.13", + "@types/phoenix": "^1.6.6", + "@types/ws": "^8.18.1", + "isows": "^1.0.7", + "ws": "^8.18.2" } }, "node_modules/@supabase/ssr": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@supabase/ssr/-/ssr-0.4.0.tgz", - "integrity": "sha512-6WS3NUvHDhCPAFN2kJ79AQDO8+M9fJ7y2fYpxgZqIuJEpnnGsHDNnB5Xnv8CiaJIuRU+0pKboy62RVZBMfZ0Lg==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@supabase/ssr/-/ssr-0.6.1.tgz", + "integrity": "sha512-QtQgEMvaDzr77Mk3vZ3jWg2/y+D8tExYF7vcJT+wQ8ysuvOeGGjYbZlvj5bHYsj/SpC0bihcisnwPrM4Gp5G4g==", + "license": "MIT", "dependencies": { - "cookie": "^0.6.0" - }, - "optionalDependencies": { - "@rollup/rollup-linux-x64-gnu": "^4.9.5" + "cookie": "^1.0.1" }, "peerDependencies": { "@supabase/supabase-js": "^2.43.4" } }, "node_modules/@supabase/storage-js": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.6.0.tgz", - "integrity": "sha512-REAxr7myf+3utMkI2oOmZ6sdplMZZ71/2NEIEMBZHL9Fkmm3/JnaOZVSRqvG4LStYj2v5WhCruCzuMn6oD/Drw==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.7.1.tgz", + "integrity": "sha512-asYHcyDR1fKqrMpytAS1zjyEfvxuOIp1CIXX7ji4lHHcJKqyk+sLl/Vxgm4sN6u8zvuUtae9e4kDxQP2qrwWBA==", + "license": "MIT", "dependencies": { "@supabase/node-fetch": "^2.6.14" } }, "node_modules/@supabase/supabase-js": { - "version": "2.44.2", - "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.44.2.tgz", - "integrity": "sha512-fouCwL1OxqftOwLNgdDUPlNnFuCnt30nS4kLcnTpe6NYKn1PmjxRRBFmKscgHs6FjWyU+32ZG4uBJ29+/BWiDw==", + "version": "2.52.0", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.52.0.tgz", + "integrity": "sha512-jbs3CV1f2+ge7sgBeEduboT9v/uGjF22v0yWi/5/XFn5tbM8MfWRccsMtsDwAwu24XK8H6wt2LJDiNnZLtx/bg==", + "license": "MIT", "dependencies": { - "@supabase/auth-js": "2.64.2", - "@supabase/functions-js": "2.4.1", + "@supabase/auth-js": "2.71.1", + "@supabase/functions-js": "2.4.5", "@supabase/node-fetch": "2.6.15", - "@supabase/postgrest-js": "1.15.7", - "@supabase/realtime-js": "2.10.2", - "@supabase/storage-js": "2.6.0" + "@supabase/postgrest-js": "1.19.4", + "@supabase/realtime-js": "2.11.15", + "@supabase/storage-js": "2.7.1" + } + }, + "node_modules/@sveltejs/acorn-typescript": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.5.tgz", + "integrity": "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^8.9.0" } }, "node_modules/@sveltejs/adapter-auto": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-3.2.2.tgz", - "integrity": "sha512-Mso5xPCA8zgcKrv+QioVlqMZkyUQ5MjDJiEPuG/Z7cV/5tmwV7LmcVWk5tZ+H0NCOV1x12AsoSpt/CwFwuVXMA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-6.0.1.tgz", + "integrity": "sha512-mcWud3pYGPWM2Pphdj8G9Qiq24nZ8L4LB7coCUckUEy5Y7wOWGJ/enaZ4AtJTcSm5dNK1rIkBRoqt+ae4zlxcQ==", "dev": true, - "dependencies": { - "import-meta-resolve": "^4.1.0" - }, + "license": "MIT", "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "node_modules/@sveltejs/kit": { - "version": "2.5.18", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.18.tgz", - "integrity": "sha512-+g06hvpVAnH7b4CDjhnTDgFWBKBiQJpuSmQeGYOuzbO3SC3tdYjRNlDCrafvDtKbGiT2uxY5Dn9qdEUGVZdWOQ==", + "version": "2.25.1", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.25.1.tgz", + "integrity": "sha512-8H+fxDEp7Xq6tLFdrGdS5fLu6ONDQQ9DgyjboXpChubuFdfH9QoFX09ypssBpyNkJNZFt9eW3yLmXIc9CesPCA==", "dev": true, - "hasInstallScript": true, + "license": "MIT", "dependencies": { + "@sveltejs/acorn-typescript": "^1.0.5", "@types/cookie": "^0.6.0", + "acorn": "^8.14.1", "cookie": "^0.6.0", - "devalue": "^5.0.0", - "esm-env": "^1.0.0", - "import-meta-resolve": "^4.1.0", + "devalue": "^5.1.0", + "esm-env": "^1.2.2", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "sade": "^1.8.1", "set-cookie-parser": "^2.6.0", - "sirv": "^2.0.4", - "tiny-glob": "^0.2.9" + "sirv": "^3.0.0" }, "bin": { "svelte-kit": "svelte-kit.js" @@ -807,94 +977,105 @@ "node": ">=18.13" }, "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^3.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0", "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.3" + "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0" + } + }, + "node_modules/@sveltejs/kit/node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.1.tgz", - "integrity": "sha512-rimpFEAboBBHIlzISibg94iP09k/KYdHgVhJlcsTfn7KMBhc70jFX/GRWkRdFCc2fdnk+4+Bdfej23cMDnJS6A==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.1.0.tgz", + "integrity": "sha512-+U6lz1wvGEG/BvQyL4z/flyNdQ9xDNv5vrh+vWBWTHaebqT0c9RNggpZTo/XSPoHsSCWBlYaTlRX8pZ9GATXCw==", "dev": true, + "license": "MIT", "dependencies": { - "@sveltejs/vite-plugin-svelte-inspector": "^2.1.0", - "debug": "^4.3.4", + "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0-next.1", + "debug": "^4.4.1", "deepmerge": "^4.3.1", "kleur": "^4.1.5", - "magic-string": "^0.30.10", - "svelte-hmr": "^0.16.0", - "vitefu": "^0.2.5" + "magic-string": "^0.30.17", + "vitefu": "^1.1.1" }, "engines": { - "node": "^18.0.0 || >=20" + "node": "^20.19 || ^22.12 || >=24" }, "peerDependencies": { - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.0" + "svelte": "^5.0.0", + "vite": "^6.3.0 || ^7.0.0" } }, "node_modules/@sveltejs/vite-plugin-svelte-inspector": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", - "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-5.0.0.tgz", + "integrity": "sha512-iwQ8Z4ET6ZFSt/gC+tVfcsSBHwsqc6RumSaiLUkAurW3BCpJam65cmHw0oOlDMTO0u+PZi9hilBRYN+LZNHTUQ==", "dev": true, + "license": "MIT", "dependencies": { - "debug": "^4.3.4" + "debug": "^4.4.1" }, "engines": { - "node": "^18.0.0 || >=20" + "node": "^20.19 || ^22.12 || >=24" }, "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^3.0.0", - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.0" + "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0", + "svelte": "^5.0.0", + "vite": "^6.3.0 || ^7.0.0" } }, "node_modules/@types/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { - "version": "20.12.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", - "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", + "version": "24.0.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.15.tgz", + "integrity": "sha512-oaeTSbCef7U/z7rDeJA138xpG3NuKc64/rZ2qmUFkFJmnMsAPaluIifqyWd8hSSMxyP9oie3dLAqYPblag9KgA==", + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~7.8.0" } }, "node_modules/@types/phoenix": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.5.tgz", - "integrity": "sha512-xegpDuR+z0UqG9fwHqNoy3rI7JDlvaPh2TY47Fl80oq6g+hXT+c/LEuE43X48clZ6lOfANl5WrPur9fYO1RJ/w==" - }, - "node_modules/@types/pug": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", - "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", - "dev": true + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.6.tgz", + "integrity": "sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==", + "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -902,157 +1083,69 @@ "node": ">=0.4.0" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "dev": true, - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/axobject-query": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", - "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", "dev": true, - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, + "license": "Apache-2.0", "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "dev": true, + "license": "Apache-2.0", "engines": { - "node": "*" + "node": ">= 0.4" } }, "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, + "license": "MIT", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "readdirp": "^4.0.1" }, "engines": { - "node": ">= 8.10.0" + "node": ">= 14.16.0" }, "funding": { "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" } }, - "node_modules/code-red": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", - "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15", - "@types/estree": "^1.0.1", - "acorn": "^8.10.0", - "estree-walker": "^3.0.3", - "periscopic": "^3.1.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=6" } }, - "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + "node": ">=18" } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -1068,117 +1161,99 @@ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/devalue": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.0.0.tgz", - "integrity": "sha512-gO+/OMXF7488D+u3ue+G7Y4AA3ZmUnB3eHJXmBTgNHvr4ZNzl36A0ZtG+XCRNYCkYx/bFmw4qtkoFLa+wSrwAA==", - "dev": true - }, - "node_modules/es6-promise": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", - "dev": true + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz", + "integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==", + "dev": true, + "license": "MIT" }, "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", + "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "@esbuild/aix-ppc64": "0.25.8", + "@esbuild/android-arm": "0.25.8", + "@esbuild/android-arm64": "0.25.8", + "@esbuild/android-x64": "0.25.8", + "@esbuild/darwin-arm64": "0.25.8", + "@esbuild/darwin-x64": "0.25.8", + "@esbuild/freebsd-arm64": "0.25.8", + "@esbuild/freebsd-x64": "0.25.8", + "@esbuild/linux-arm": "0.25.8", + "@esbuild/linux-arm64": "0.25.8", + "@esbuild/linux-ia32": "0.25.8", + "@esbuild/linux-loong64": "0.25.8", + "@esbuild/linux-mips64el": "0.25.8", + "@esbuild/linux-ppc64": "0.25.8", + "@esbuild/linux-riscv64": "0.25.8", + "@esbuild/linux-s390x": "0.25.8", + "@esbuild/linux-x64": "0.25.8", + "@esbuild/netbsd-arm64": "0.25.8", + "@esbuild/netbsd-x64": "0.25.8", + "@esbuild/openbsd-arm64": "0.25.8", + "@esbuild/openbsd-x64": "0.25.8", + "@esbuild/openharmony-arm64": "0.25.8", + "@esbuild/sunos-x64": "0.25.8", + "@esbuild/win32-arm64": "0.25.8", + "@esbuild/win32-ia32": "0.25.8", + "@esbuild/win32-x64": "0.25.8" } }, "node_modules/esm-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", - "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==", - "dev": true + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", + "dev": true, + "license": "MIT" }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "node_modules/esrap": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.1.0.tgz", + "integrity": "sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==", "dev": true, + "license": "MIT", "dependencies": { - "@types/estree": "^1.0.0" + "@jridgewell/sourcemap-codec": "^1.4.15" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" }, - "engines": { - "node": ">=8" + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -1187,131 +1262,29 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globalyzer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", - "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", - "dev": true - }, - "node_modules/globrex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", - "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", - "dev": true - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/import-meta-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", - "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/is-reference": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", "dev": true, + "license": "MIT", "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "@types/estree": "^1.0.6" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-reference": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", - "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", - "dev": true, - "dependencies": { - "@types/estree": "*" + "node_modules/isows": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", + "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "peerDependencies": { + "ws": "*" } }, "node_modules/kleur": { @@ -1319,6 +1292,7 @@ "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1327,63 +1301,17 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", - "dev": true - }, - "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - }, - "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } + "license": "MIT" }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "dev": true, + "license": "MIT", "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/mri": { @@ -1391,29 +1319,32 @@ "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/mrmime": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", - "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { @@ -1421,6 +1352,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -1428,66 +1360,30 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" - } - }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "funding": [ { @@ -1503,46 +1399,38 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, + "license": "MIT", "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" + "node": ">= 14.18.0" }, - "bin": { - "rimraf": "bin.js" + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, "node_modules/rollup": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.2.tgz", - "integrity": "sha512-WkeoTWvuBoFjFAhsEOHKRoZ3r9GfTyhh7Vff1zwebEFLEFjT1lG3784xEgKiTa7E+e70vsC81roVL2MP4tgEEQ==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.45.1.tgz", + "integrity": "sha512-4iya7Jb76fVpQyLoiVpzUrsjQ12r3dM7fIVz+4NwoYvZOShknRmiv+iu9CClZml5ZLGb0XMcYLutK6w9tgxHDw==", "dev": true, + "license": "MIT", "dependencies": { - "@types/estree": "1.0.5" + "@types/estree": "1.0.8" }, "bin": { "rollup": "dist/bin/rollup" @@ -1552,21 +1440,26 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.14.2", - "@rollup/rollup-android-arm64": "4.14.2", - "@rollup/rollup-darwin-arm64": "4.14.2", - "@rollup/rollup-darwin-x64": "4.14.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.14.2", - "@rollup/rollup-linux-arm64-gnu": "4.14.2", - "@rollup/rollup-linux-arm64-musl": "4.14.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.14.2", - "@rollup/rollup-linux-riscv64-gnu": "4.14.2", - "@rollup/rollup-linux-s390x-gnu": "4.14.2", - "@rollup/rollup-linux-x64-gnu": "4.14.2", - "@rollup/rollup-linux-x64-musl": "4.14.2", - "@rollup/rollup-win32-arm64-msvc": "4.14.2", - "@rollup/rollup-win32-ia32-msvc": "4.14.2", - "@rollup/rollup-win32-x64-msvc": "4.14.2", + "@rollup/rollup-android-arm-eabi": "4.45.1", + "@rollup/rollup-android-arm64": "4.45.1", + "@rollup/rollup-darwin-arm64": "4.45.1", + "@rollup/rollup-darwin-x64": "4.45.1", + "@rollup/rollup-freebsd-arm64": "4.45.1", + "@rollup/rollup-freebsd-x64": "4.45.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.45.1", + "@rollup/rollup-linux-arm-musleabihf": "4.45.1", + "@rollup/rollup-linux-arm64-gnu": "4.45.1", + "@rollup/rollup-linux-arm64-musl": "4.45.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.45.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.45.1", + "@rollup/rollup-linux-riscv64-gnu": "4.45.1", + "@rollup/rollup-linux-riscv64-musl": "4.45.1", + "@rollup/rollup-linux-s390x-gnu": "4.45.1", + "@rollup/rollup-linux-x64-gnu": "4.45.1", + "@rollup/rollup-linux-x64-musl": "4.45.1", + "@rollup/rollup-win32-arm64-msvc": "4.45.1", + "@rollup/rollup-win32-ia32-msvc": "4.45.1", + "@rollup/rollup-win32-x64-msvc": "4.45.1", "fsevents": "~2.3.2" } }, @@ -1575,6 +1468,7 @@ "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", "dev": true, + "license": "MIT", "dependencies": { "mri": "^1.1.0" }, @@ -1582,214 +1476,103 @@ "node": ">=6" } }, - "node_modules/sander": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", - "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", - "dev": true, - "dependencies": { - "es6-promise": "^3.1.2", - "graceful-fs": "^4.1.3", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.2" - } - }, "node_modules/set-cookie-parser": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", - "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==", - "dev": true + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "dev": true, + "license": "MIT" }, "node_modules/sirv": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", - "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.1.tgz", + "integrity": "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==", "dev": true, + "license": "MIT", "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" }, "engines": { - "node": ">= 10" - } - }, - "node_modules/sorcery": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.0.tgz", - "integrity": "sha512-J69LQ22xrQB1cIFJhPfgtLuI6BpWRiWu1Y3vSsIwK/eAScqJxd/+CJlUuHQRdX2C9NGFamq+KqNywGgaThwfHw==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.14", - "buffer-crc32": "^0.2.5", - "minimist": "^1.2.0", - "sander": "^0.5.0" - }, - "bin": { - "sorcery": "bin/sorcery" + "node": ">=18" } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/svelte": { - "version": "4.2.18", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.18.tgz", - "integrity": "sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==", + "version": "5.36.12", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.36.12.tgz", + "integrity": "sha512-c3mWT+b0yBLl3gPGSHiy4pdSQCsPNTjLC0tVoOhrGJ6PPfCzD/RQpAmAfJtQZ304CAae2ph+L3C4aqds3R3seQ==", "dev": true, + "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.2.1", - "@jridgewell/sourcemap-codec": "^1.4.15", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/estree": "^1.0.1", - "acorn": "^8.9.0", - "aria-query": "^5.3.0", - "axobject-query": "^4.0.0", - "code-red": "^1.0.3", - "css-tree": "^2.3.1", - "estree-walker": "^3.0.3", - "is-reference": "^3.0.1", + "@ampproject/remapping": "^2.3.0", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@sveltejs/acorn-typescript": "^1.0.5", + "@types/estree": "^1.0.5", + "acorn": "^8.12.1", + "aria-query": "^5.3.1", + "axobject-query": "^4.1.0", + "clsx": "^2.1.1", + "esm-env": "^1.2.1", + "esrap": "^2.1.0", + "is-reference": "^3.0.3", "locate-character": "^3.0.0", - "magic-string": "^0.30.4", - "periscopic": "^3.1.0" + "magic-string": "^0.30.11", + "zimmerframe": "^1.1.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/svelte-check": { - "version": "3.8.4", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.8.4.tgz", - "integrity": "sha512-61aHMkdinWyH8BkkTX9jPLYxYzaAAz/FK/VQqdr2FiCQQ/q04WCwDlpGbHff1GdrMYTmW8chlTFvRWL9k0A8vg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.3.0.tgz", + "integrity": "sha512-Iz8dFXzBNAM7XlEIsUjUGQhbEE+Pvv9odb9+0+ITTgFWZBGeJRRYqHUUglwe2EkLD5LIsQaAc4IUJyvtKuOO5w==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.17", - "chokidar": "^3.4.1", + "@jridgewell/trace-mapping": "^0.3.25", + "chokidar": "^4.0.1", + "fdir": "^6.2.0", "picocolors": "^1.0.0", - "sade": "^1.7.4", - "svelte-preprocess": "^5.1.3", - "typescript": "^5.0.3" + "sade": "^1.7.4" }, "bin": { "svelte-check": "bin/svelte-check" }, - "peerDependencies": { - "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0" - } - }, - "node_modules/svelte-hmr": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", - "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", - "dev": true, "engines": { - "node": "^12.20 || ^14.13.1 || >= 16" + "node": ">= 18.0.0" }, "peerDependencies": { - "svelte": "^3.19.0 || ^4.0.0" + "svelte": "^4.0.0 || ^5.0.0-next.0", + "typescript": ">=5.0.0" } }, - "node_modules/svelte-preprocess": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.3.tgz", - "integrity": "sha512-xxAkmxGHT+J/GourS5mVJeOXZzne1FR5ljeOUAMXUkfEhkLEllRreXpbl3dIYJlcJRfL1LO1uIAPpBpBfiqGPw==", + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", "dev": true, - "hasInstallScript": true, + "license": "MIT", "dependencies": { - "@types/pug": "^2.0.6", - "detect-indent": "^6.1.0", - "magic-string": "^0.30.5", - "sorcery": "^0.11.0", - "strip-indent": "^3.0.0" + "fdir": "^6.4.4", + "picomatch": "^4.0.2" }, "engines": { - "node": ">= 16.0.0", - "pnpm": "^8.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.10.2", - "coffeescript": "^2.5.1", - "less": "^3.11.3 || ^4.0.0", - "postcss": "^7 || ^8", - "postcss-load-config": "^2.1.0 || ^3.0.0 || ^4.0.0 || ^5.0.0", - "pug": "^3.0.0", - "sass": "^1.26.8", - "stylus": "^0.55.0", - "sugarss": "^2.0.0 || ^3.0.0 || ^4.0.0", - "svelte": "^3.23.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0", - "typescript": ">=3.9.5 || ^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "coffeescript": { - "optional": true - }, - "less": { - "optional": true - }, - "postcss": { - "optional": true - }, - "postcss-load-config": { - "optional": true - }, - "pug": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/tiny-glob": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", - "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", - "dev": true, - "dependencies": { - "globalyzer": "0.1.0", - "globrex": "^0.1.2" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" + "node": ">=12.0.0" }, - "engines": { - "node": ">=8.0" + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" } }, "node_modules/totalist": { @@ -1797,6 +1580,7 @@ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1804,19 +1588,22 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", - "dev": true + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1826,25 +1613,30 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "license": "MIT" }, "node_modules/vite": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.3.tgz", - "integrity": "sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.5.tgz", + "integrity": "sha512-1mncVwJxy2C9ThLwz0+2GKZyEXuC3MyWtAAlNftlZZXZDP3AJt5FmwcMit/IGGaNZ8ZOB2BNO/HFUB+CpN0NQw==", "dev": true, + "license": "MIT", "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.39", - "rollup": "^4.13.0" + "esbuild": "^0.25.0", + "fdir": "^6.4.6", + "picomatch": "^4.0.2", + "postcss": "^8.5.6", + "rollup": "^4.40.0", + "tinyglobby": "^0.2.14" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -1853,18 +1645,25 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, + "jiti": { + "optional": true + }, "less": { "optional": true }, @@ -1874,6 +1673,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, @@ -1882,16 +1684,28 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } }, "node_modules/vitefu": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", - "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.1.tgz", + "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", "dev": true, + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "peerDependenciesMeta": { "vite": { @@ -1902,27 +1716,24 @@ "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, "node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -1938,6 +1749,13 @@ "optional": true } } + }, + "node_modules/zimmerframe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz", + "integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==", + "dev": true, + "license": "MIT" } } } diff --git a/examples/user-management/sveltekit-user-management/package.json b/examples/user-management/sveltekit-user-management/package.json index 79107528d4501..54c0d1bfcb432 100644 --- a/examples/user-management/sveltekit-user-management/package.json +++ b/examples/user-management/sveltekit-user-management/package.json @@ -10,20 +10,20 @@ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" }, "devDependencies": { - "@sveltejs/adapter-auto": "^3.2.2", - "@sveltejs/kit": "^2.5.18", - "@sveltejs/vite-plugin-svelte": "^3.1.1", - "svelte": "^4.2.18", - "svelte-check": "^3.8.4", + "@sveltejs/adapter-auto": "^6.0.1", + "@sveltejs/kit": "^2.5.27", + "@sveltejs/vite-plugin-svelte": "^6.1.0", + "svelte": "^5.14.4", + "svelte-check": "^4.1.1", "tslib": "^2.6.3", "typescript": "^5.5.3", - "vite": "^5.3.3" + "vite": "^7.0.5" }, "type": "module", "dependencies": { "@supabase/auth-ui-shared": "^0.1.8", "@supabase/auth-ui-svelte": "^0.2.9", - "@supabase/ssr": "^0.4.0", + "@supabase/ssr": "^0.6.1", "@supabase/supabase-js": "^2.44.2" } } diff --git a/examples/user-management/sveltekit-user-management/src/routes/+layout.svelte b/examples/user-management/sveltekit-user-management/src/routes/+layout.svelte index 2a6939f7ccfee..50611f57fd0f1 100644 --- a/examples/user-management/sveltekit-user-management/src/routes/+layout.svelte +++ b/examples/user-management/sveltekit-user-management/src/routes/+layout.svelte @@ -4,10 +4,8 @@ import { invalidate } from '$app/navigation' import { onMount } from 'svelte' - export let data - - let { supabase, session } = data - $: ({ supabase, session } = data) + let { data, children } = $props() + let { supabase, session } = $derived(data) onMount(() => { const { data } = supabase.auth.onAuthStateChange((event, _session) => { @@ -25,5 +23,5 @@
    - + {@render children()}
    \ No newline at end of file diff --git a/examples/user-management/sveltekit-user-management/src/routes/+page.svelte b/examples/user-management/sveltekit-user-management/src/routes/+page.svelte index 84f43c0e76441..0d1d986a08d38 100644 --- a/examples/user-management/sveltekit-user-management/src/routes/+page.svelte +++ b/examples/user-management/sveltekit-user-management/src/routes/+page.svelte @@ -3,9 +3,12 @@ import { enhance } from '$app/forms' import type { ActionData, SubmitFunction } from './$types.js' - export let form: ActionData; - - let loading = false + interface Props { + form: ActionData + } + let { form }: Props = $props() + + let loading = $state(false) const handleSubmit: SubmitFunction = () => { loading = true diff --git a/examples/user-management/sveltekit-user-management/src/routes/account/+page.svelte b/examples/user-management/sveltekit-user-management/src/routes/account/+page.svelte index 7ba596dc5041f..dde5b75046266 100644 --- a/examples/user-management/sveltekit-user-management/src/routes/account/+page.svelte +++ b/examples/user-management/sveltekit-user-management/src/routes/account/+page.svelte @@ -1,21 +1,16 @@ -
    @@ -73,7 +76,7 @@ style="height: {size}em; width: {size}em;" /> {:else} -
    +
    {/if} @@ -87,7 +90,7 @@ id="single" accept="image/*" bind:files - on:change={uploadAvatar} + onchange={uploadAvatar} disabled={uploading} />
    diff --git a/examples/user-management/sveltekit-user-management/src/routes/auth/error/+page.svelte b/examples/user-management/sveltekit-user-management/src/routes/auth/error/+page.svelte new file mode 100644 index 0000000000000..0176f4c72e6a0 --- /dev/null +++ b/examples/user-management/sveltekit-user-management/src/routes/auth/error/+page.svelte @@ -0,0 +1 @@ +

    Login error

    \ No newline at end of file diff --git a/package.json b/package.json index 110e56924733a..e7e3e31feafb9 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,6 @@ "test:ui-patterns": "turbo run test --filter=ui-patterns", "test:studio": "turbo run test --filter=studio", "test:studio:watch": "turbo run test --filter=studio -- watch", - "e2e": "pnpm --prefix e2e/studio run e2e", "e2e:dev-hosted": "pnpm --prefix e2e/studio run e2e:dev-hosted", "e2e:dev-selfhosted": "pnpm --prefix e2e/studio run e2e:dev-selfhosted", @@ -39,7 +38,6 @@ "e2e:ci": "pnpm --prefix e2e/studio run e2e:ci", "e2e:supabase:start": "pnpm --prefix e2e/studio run supabase:start", "e2e:supabase:stop": "pnpm --prefix e2e/studio run supabase:stop", - "perf:kong": "ab -t 5 -c 20 -T application/json http://localhost:8000/", "perf:meta": "ab -t 5 -c 20 -T application/json http://localhost:5555/tables", "setup:cli": "supabase start -x studio && supabase status --output json > keys.json && node scripts/generateLocalEnv.js", @@ -72,12 +70,21 @@ "esbuild": "^0.25.2", "@redocly/respect-core>form-data": "^4.0.4" }, - "neverBuiltDependencies": ["libpg-query"] + "neverBuiltDependencies": [ + "libpg-query" + ] }, "engines": { "pnpm": ">=9", "node": ">=22" }, - "keywords": ["postgres", "firebase", "storage", "functions", "database", "auth"], + "keywords": [ + "postgres", + "firebase", + "storage", + "functions", + "database", + "auth" + ], "packageManager": "pnpm@9.15.5" -} +} \ No newline at end of file From 6424ae4c31cb516301ab3e87e1069bb34df9c9f3 Mon Sep 17 00:00:00 2001 From: Jordi Enric <37541088+jordienr@users.noreply.github.com> Date: Tue, 12 Aug 2025 17:18:13 +0200 Subject: [PATCH 5/7] move sentry client config to instrumentation-client.ts (#37871) * add instrumentation-client * add env to turbojson so it dont yell at me --- .../{sentry.client.config.ts => instrumentation-client.ts} | 0 turbo.json | 1 + 2 files changed, 1 insertion(+) rename apps/studio/{sentry.client.config.ts => instrumentation-client.ts} (100%) diff --git a/apps/studio/sentry.client.config.ts b/apps/studio/instrumentation-client.ts similarity index 100% rename from apps/studio/sentry.client.config.ts rename to apps/studio/instrumentation-client.ts diff --git a/turbo.json b/turbo.json index c1a8a6dc53fc0..6d010af23b408 100644 --- a/turbo.json +++ b/turbo.json @@ -90,6 +90,7 @@ "SENTRY_ORG", "SENTRY_PROJECT", "SENTRY_AUTH_TOKEN", + "NEXT_PUBLIC_SENTRY_DSN", "AWS_BEDROCK_PROFILE", "AWS_BEDROCK_ROLE_ARN", "AWS_ACCESS_KEY_ID", From a25716393596886f8fddfae4036e7f95414fdbdb Mon Sep 17 00:00:00 2001 From: Tyler Date: Tue, 12 Aug 2025 10:18:52 -0500 Subject: [PATCH 6/7] blog: Swap the videos on the lw15 blog posts with the deep dive videos (#37873) --- apps/www/_blog/2025-07-14-jwt-signing-keys.mdx | 2 +- apps/www/_blog/2025-07-15-analytics-buckets.mdx | 2 +- apps/www/_blog/2025-07-16-branching-2-0.mdx | 2 +- .../2025-07-18-persistent-storage-for-faster-edge-functions.mdx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/www/_blog/2025-07-14-jwt-signing-keys.mdx b/apps/www/_blog/2025-07-14-jwt-signing-keys.mdx index 168a61242e0a5..7fd4efac42ee6 100644 --- a/apps/www/_blog/2025-07-14-jwt-signing-keys.mdx +++ b/apps/www/_blog/2025-07-14-jwt-signing-keys.mdx @@ -22,7 +22,7 @@ Today we're announcing some long awaited changes in Supabase: