From 83681d036a15bde42b9cac5ada22481de826cb6d Mon Sep 17 00:00:00 2001 From: Ignacio Dobronich Date: Fri, 5 Jun 2026 14:14:59 -0300 Subject: [PATCH 001/134] feat: purchasing as business tooltip (#46659) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds an info tooltip next to the "I'm purchasing as a business" checkbox explaining that it's for tax-registered businesses and requires a tax ID. ## Summary by CodeRabbit * **New Features** * Added a help icon with tooltip next to the "I’m purchasing as a business" checkbox. The tooltip clarifies when to select the business option and notes that tax ID entry is required only for tax‑registered businesses, reducing confusion and helping users provide correct billing information. --- .../PaymentMethods/NewPaymentMethodElement.tsx | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/studio/components/interfaces/Billing/Payment/PaymentMethods/NewPaymentMethodElement.tsx b/apps/studio/components/interfaces/Billing/Payment/PaymentMethods/NewPaymentMethodElement.tsx index 6c6abcc3d92..183684a6d5a 100644 --- a/apps/studio/components/interfaces/Billing/Payment/PaymentMethods/NewPaymentMethodElement.tsx +++ b/apps/studio/components/interfaces/Billing/Payment/PaymentMethods/NewPaymentMethodElement.tsx @@ -12,7 +12,7 @@ import { type SetupIntent, } from '@stripe/stripe-js' import { Form } from '@ui/components/shadcn/ui/form' -import { Check, ChevronsUpDown } from 'lucide-react' +import { Check, ChevronsUpDown, HelpCircle } from 'lucide-react' import { forwardRef, useEffect, useId, useImperativeHandle, useMemo, useRef, useState } from 'react' import { useForm } from 'react-hook-form' import { toast } from 'sonner' @@ -34,6 +34,9 @@ import { Popover, PopoverContent, PopoverTrigger, + Tooltip, + TooltipContent, + TooltipTrigger, } from 'ui' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import { z } from 'zod' @@ -345,6 +348,19 @@ export const NewPaymentMethodElement = forwardRef( + + + + + + Select this only if your business is tax-registered. You’ll be asked for a tax ID + (e.g. US EIN, VAT, GST), which is required to issue a compliant business invoice. If + you’re not tax-registered, leave this unchecked. You’ll still receive a receipt. + + )} From c0e0501c010dd5e32ab17d0b3c6ee01d13c0630c Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Fri, 5 Jun 2026 14:02:23 -0400 Subject: [PATCH 002/134] feat(studio): support custom installation logic for marketplace integrations (#46660) - Fetch additional project data needed to determine marketplace integration installation status - Consolidate logic to ensure consistency between left-hand nav and overview tab - Add special-case handling of new integrations to give us more granular control of their behavior --- .../InstallOAuthIntegrationButton.tsx | 63 +------ .../Landing/Integrations.constants.tsx | 1 + .../Integrations/Landing/Landing.utils.ts | 163 +++++++++++++++--- .../Landing/useAvailableIntegrations.tsx | 2 + .../Landing/useInstalledIntegrations.tsx | 89 ++-------- packages/common/marketplace.types.ts | 2 +- 6 files changed, 166 insertions(+), 154 deletions(-) diff --git a/apps/studio/components/interfaces/Integrations/Integration/IntegrationOverviewTabV2/InstallIntegrationSheet/InstallOAuthIntegrationButton.tsx b/apps/studio/components/interfaces/Integrations/Integration/IntegrationOverviewTabV2/InstallIntegrationSheet/InstallOAuthIntegrationButton.tsx index 362aa65617a..06f4a50cc84 100644 --- a/apps/studio/components/interfaces/Integrations/Integration/IntegrationOverviewTabV2/InstallIntegrationSheet/InstallOAuthIntegrationButton.tsx +++ b/apps/studio/components/interfaces/Integrations/Integration/IntegrationOverviewTabV2/InstallIntegrationSheet/InstallOAuthIntegrationButton.tsx @@ -3,11 +3,9 @@ import { useMemo } from 'react' import { toast } from 'sonner' import { Button } from 'ui' +import { isOAuthInstalled, useProjectOAuthIntegrationData } from '../../../Landing/Landing.utils' import type { IntegrationDefinition } from '@/components/interfaces/Integrations/Landing/Integrations.constants' -import { useAPIKeysQuery } from '@/data/api-keys/api-keys-query' import { useInstallOAuthIntegrationMutation } from '@/data/marketplace/install-oauth-integration-mutation' -import { usePartnerIntegrationsQuery } from '@/data/partners/integration-status-query' -import { useSecretsQuery } from '@/data/secrets/secrets-query' interface InstallOAuthIntegrationButtonProps { integration: IntegrationDefinition @@ -16,28 +14,7 @@ interface InstallOAuthIntegrationButtonProps { export function InstallOAuthIntegrationButton({ integration }: InstallOAuthIntegrationButtonProps) { const { ref: projectRef } = useParams() - const requiresApiKeysCheck = - integration.installIdentificationMethod === 'secret_key_prefix' && !!integration.secretKeyPrefix - - const requiresEdgeFunctionSecretsCheck = - integration.installIdentificationMethod === 'edge_function_secret_name' && - !!integration.edgeFunctionSecretName - - const requiresPartnerIntegrationsCheck = - integration.installIdentificationMethod === 'integration_status' - - const { data: apiKeys, isLoading: isApiKeysLoading } = useAPIKeysQuery( - { projectRef, reveal: false }, - { enabled: requiresApiKeysCheck } - ) - - const { data: edgeFunctionSecrets, isPending: isEdgeFunctionSecretsLoading } = useSecretsQuery( - { projectRef }, - { enabled: requiresEdgeFunctionSecretsCheck } - ) - - const { data: partnerIntegrations, isPending: isPartnerIntegrationsLoading } = - usePartnerIntegrationsQuery({ projectRef }, { enabled: requiresPartnerIntegrationsCheck }) + const { data, isLoading } = useProjectOAuthIntegrationData(projectRef) const { mutate: installOAuthIntegration, isPending: isInstalling } = useInstallOAuthIntegrationMutation({ @@ -54,43 +31,11 @@ export function InstallOAuthIntegrationButton({ integration }: InstallOAuthInteg }, }) - const isLoading = - (requiresApiKeysCheck && isApiKeysLoading) || - (requiresEdgeFunctionSecretsCheck && isEdgeFunctionSecretsLoading) || - (requiresPartnerIntegrationsCheck && isPartnerIntegrationsLoading) - const isIntegrationInstalled = useMemo(() => { if (!integration) return false - if (integration.installIdentificationMethod === 'secret_key_prefix') { - const prefix = integration.secretKeyPrefix - if (!prefix || isApiKeysLoading || !apiKeys) return false - return apiKeys.some((k) => k.type === 'secret' && k.name.startsWith(prefix)) - } - - if (integration.installIdentificationMethod === 'edge_function_secret_name') { - const secretName = integration.edgeFunctionSecretName - if (!secretName || isEdgeFunctionSecretsLoading || !edgeFunctionSecrets) return false - return edgeFunctionSecrets.some((secret) => secret.name === secretName) - } - - if (integration.installIdentificationMethod === 'integration_status') { - if (isPartnerIntegrationsLoading || !partnerIntegrations) return false - return partnerIntegrations.some( - (i) => i.listing_slug === integration.id && i.status === 'ready' - ) - } - - return false - }, [ - apiKeys, - edgeFunctionSecrets, - partnerIntegrations, - integration, - isApiKeysLoading, - isEdgeFunctionSecretsLoading, - isPartnerIntegrationsLoading, - ]) + return isOAuthInstalled({ integration, projectData: data }) + }, [data, integration]) const handleInstallClick = async () => { if (!integration || !projectRef) return diff --git a/apps/studio/components/interfaces/Integrations/Landing/Integrations.constants.tsx b/apps/studio/components/interfaces/Integrations/Landing/Integrations.constants.tsx index c650c29d021..c8e59f07d48 100644 --- a/apps/studio/components/interfaces/Integrations/Landing/Integrations.constants.tsx +++ b/apps/studio/components/interfaces/Integrations/Landing/Integrations.constants.tsx @@ -118,6 +118,7 @@ export type IntegrationDefinition = { secretKeyPrefix?: string edgeFunctionSecretName?: string listingId?: string + oauthAppId?: string } & ( | { type: 'wrapper'; meta: WrapperMeta } | { type: 'postgres_extension' | 'custom' | 'oauth' | 'template' } diff --git a/apps/studio/components/interfaces/Integrations/Landing/Landing.utils.ts b/apps/studio/components/interfaces/Integrations/Landing/Landing.utils.ts index 50024118dbd..16edbd37d11 100644 --- a/apps/studio/components/interfaces/Integrations/Landing/Landing.utils.ts +++ b/apps/studio/components/interfaces/Integrations/Landing/Landing.utils.ts @@ -1,3 +1,4 @@ +import { useMemo } from 'react' import { parseSchemaComment } from 'stripe-experiment-sync/supabase' import { type WrapperMeta } from '../Wrappers/Wrappers.types' @@ -7,12 +8,19 @@ import { isInstalled as checkIsInstalled, findStripeSchema, } from '@/components/interfaces/Integrations/templates/StripeSyncEngine/stripe-sync-status' -import { type APIKey } from '@/data/api-keys/api-keys-query' +import { useAPIKeysQuery, type APIKey } from '@/data/api-keys/api-keys-query' +import { ProjectAuthConfigData, useAuthConfigQuery } from '@/data/auth/auth-config-query' import { type DatabaseExtension } from '@/data/database-extensions/database-extensions-query' import { type Schema } from '@/data/database/schemas-query' import { type FDW } from '@/data/fdw/fdws-query' -import { IntegrationStatus } from '@/data/partners/integration-status-query' -import { type ProjectSecret } from '@/data/secrets/secrets-query' +import { AuthorizedApp, useAuthorizedAppsQuery } from '@/data/oauth/authorized-apps-query' +import { + IntegrationStatus, + usePartnerIntegrationsQuery, +} from '@/data/partners/integration-status-query' +import { useSecretsQuery, type ProjectSecret } from '@/data/secrets/secrets-query' +import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' +import { ResponseError } from '@/types' export const isStripeSyncEngineInstalled = (schemas: Schema[]) => { const stripeSchema = findStripeSchema(schemas) @@ -20,35 +28,150 @@ export const isStripeSyncEngineInstalled = (schemas: Schema[]) => { return checkIsInstalled(parsedSchema.status) } +type ProjectOAuthIntegrationData = { + apiKeys: APIKey[] + edgeFunctionSecrets: ProjectSecret[] + authConfig: ProjectAuthConfigData | undefined + partnerIntegrations: IntegrationStatus[] + oauthApps: AuthorizedApp[] +} + +/** + * Gathers all the information needed to determine if an arbitrary OAuth integration is installed. + */ +export const useProjectOAuthIntegrationData = ( + projectRef: string | undefined, + { enabled = true } = {} +): { + data: ProjectOAuthIntegrationData + error: ResponseError | null + isError: boolean + isLoading: boolean + isPending: boolean + isSuccess: boolean +} => { + const { data: org } = useSelectedOrganizationQuery({ enabled }) + const queries = { + apiKeys: useAPIKeysQuery({ projectRef, reveal: false }, { enabled }), + edgeFunctionSecrets: useSecretsQuery({ projectRef }, { enabled }), + authConfig: useAuthConfigQuery({ projectRef }, { enabled }), + partnerIntegrations: usePartnerIntegrationsQuery({ projectRef }, { enabled }), + oauthApps: useAuthorizedAppsQuery({ slug: org?.slug }, { enabled: !!org }), + } + + // memoize to prevent object creation from triggering a re-render when the result data is used + // as a dependency. + const data = useMemo(() => { + return { + apiKeys: queries.apiKeys.data ?? [], + edgeFunctionSecrets: queries.edgeFunctionSecrets.data ?? [], + authConfig: queries.authConfig.data, + partnerIntegrations: queries.partnerIntegrations.data ?? [], + oauthApps: queries.oauthApps.data ?? [], + } + }, [ + queries.apiKeys.data, + queries.edgeFunctionSecrets.data, + queries.authConfig.data, + queries.partnerIntegrations.data, + queries.oauthApps.data, + ]) + + return { + data, + error: + Object.values(queries) + .map((q) => q.error) + .find((e) => !!e) || null, + isError: Object.values(queries).some((x) => x.isError), + isLoading: Object.values(queries).some((x) => x.isLoading), + isPending: Object.values(queries).some((x) => x.isPending), + isSuccess: Object.values(queries).every((x) => x.isSuccess), + } +} + +const isPartnerIntegrationReady = ( + projectData: ProjectOAuthIntegrationData, + integration: IntegrationDefinition +) => { + return projectData.partnerIntegrations.some( + (i) => i.listing_slug === integration.id && i.status === 'ready' + ) +} + +const isOAuthAppAuthorized = ( + projectData: ProjectOAuthIntegrationData, + integration: IntegrationDefinition +) => { + return ( + !!integration.oauthAppId && + projectData.oauthApps.some((app) => app.app_id === integration.oauthAppId) + ) +} + +const isSecretKeyPrefixPresent = (projectData: ProjectOAuthIntegrationData, prefix?: string) => { + if (!prefix) return false + return projectData.apiKeys.some((key) => key.type === 'secret' && key.name.startsWith(prefix)) +} + +const isEdgeFunctionSecretPresent = ( + projectData: ProjectOAuthIntegrationData, + secretName?: string +) => { + if (!secretName) return false + return projectData.edgeFunctionSecrets.some((secret) => secret.name === secretName) +} + export const isOAuthInstalled = ({ integration, - apiKeys, - secrets, - partnerIntegrations: partnerIntegrations, + projectData, }: { integration: IntegrationDefinition - apiKeys: APIKey[] - secrets: ProjectSecret[] - partnerIntegrations: IntegrationStatus[] + projectData: ProjectOAuthIntegrationData }) => { - if (integration.installIdentificationMethod === 'integration_status') { - return partnerIntegrations.some( - (i) => i.listing_slug === integration.id && i.status === 'ready' + // Special-case logic for in-development integrations + if (integration.id === 'resend') { + return ( + projectData.authConfig?.SMTP_HOST === 'smtp.resend.com' && + // Keying off of OAuth App instead of integration status lets us show the integration as + // installed for partner-initiated connections, without degrading the experience for + // marketplace-initiated installations. + isOAuthAppAuthorized(projectData, integration) ) } - if (integration.installIdentificationMethod === 'secret_key_prefix') { - const prefix = integration.secretKeyPrefix - if (!prefix) return false + if (integration.id === 'grafana') { + // Grafana is not yet sending integration status, so just use presence of API key. + return isSecretKeyPrefixPresent(projectData, 'grafana_cloud_integration_') + } - return apiKeys.some((key) => key.type === 'secret' && key.name.startsWith(prefix)) + if (integration.id === 'aikido') { + return isOAuthAppAuthorized(projectData, integration) + } + + if (integration.id === 'doppler') { + return ( + isEdgeFunctionSecretPresent(projectData, 'DOPPLER_CONFIG') && + isPartnerIntegrationReady(projectData, integration) + ) + } + + // Fallback logic for generic OAuth integrations. + if (integration.installIdentificationMethod === 'integration_status') { + return isPartnerIntegrationReady(projectData, integration) + } + + if (integration.installIdentificationMethod === 'oauth_authorization') { + return isOAuthAppAuthorized(projectData, integration) + } + + // Special-case logic that is still encoded as database fields, consider removing. + if (integration.installIdentificationMethod === 'secret_key_prefix') { + return isSecretKeyPrefixPresent(projectData, integration.secretKeyPrefix) } if (integration.installIdentificationMethod === 'edge_function_secret_name') { - const secretName = integration.edgeFunctionSecretName - if (!secretName) return false - - return secrets.some((secret) => secret.name === secretName) + return isEdgeFunctionSecretPresent(projectData, integration.edgeFunctionSecretName) } return false diff --git a/apps/studio/components/interfaces/Integrations/Landing/useAvailableIntegrations.tsx b/apps/studio/components/interfaces/Integrations/Landing/useAvailableIntegrations.tsx index a65e1167846..2dd5d116ce4 100644 --- a/apps/studio/components/interfaces/Integrations/Landing/useAvailableIntegrations.tsx +++ b/apps/studio/components/interfaces/Integrations/Landing/useAvailableIntegrations.tsx @@ -83,6 +83,7 @@ export const useAvailableIntegrations = () => { content, built_by: authorName, listing_logo: listingLogo, + oauth_app_id: oauthAppId, } = integration const status = undefined @@ -109,6 +110,7 @@ export const useAvailableIntegrations = () => { installIdentificationMethod: installMethod ?? undefined, secretKeyPrefix: secretKeyPrefix ?? undefined, edgeFunctionSecretName: edgeFunctionSecretName ?? undefined, + oauthAppId: oauthAppId ?? undefined, listingId: listingId ?? undefined, author, requiredExtensions: [], diff --git a/apps/studio/components/interfaces/Integrations/Landing/useInstalledIntegrations.tsx b/apps/studio/components/interfaces/Integrations/Landing/useInstalledIntegrations.tsx index cc0510b12a6..e17ce5e617c 100644 --- a/apps/studio/components/interfaces/Integrations/Landing/useInstalledIntegrations.tsx +++ b/apps/studio/components/interfaces/Integrations/Landing/useInstalledIntegrations.tsx @@ -5,14 +5,12 @@ import { hasRequiredExtensions, isOAuthInstalled, isStripeSyncEngineInstalled, + useProjectOAuthIntegrationData, } from './Landing.utils' import { useAvailableIntegrations } from './useAvailableIntegrations' -import { useAPIKeysQuery } from '@/data/api-keys/api-keys-query' import { useDatabaseExtensionsQuery } from '@/data/database-extensions/database-extensions-query' import { useSchemasQuery } from '@/data/database/schemas-query' import { useFDWsQuery } from '@/data/fdw/fdws-query' -import { usePartnerIntegrationsQuery } from '@/data/partners/integration-status-query' -import { useSecretsQuery } from '@/data/secrets/secrets-query' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import { EMPTY_ARR } from '@/lib/void' @@ -27,64 +25,17 @@ export const useInstalledIntegrations = () => { isError: isErrorAvailableIntegrations, } = useAvailableIntegrations() - const hasSecretKeyPrefixIntegration = useMemo(() => { - return allIntegrations.some( - (integration) => - integration.type === 'oauth' && - integration.installIdentificationMethod === 'secret_key_prefix' && - !!integration.secretKeyPrefix - ) - }, [allIntegrations]) - - const hasEdgeFunctionSecretNameIntegration = useMemo(() => { - return allIntegrations.some( - (integration) => - integration.type === 'oauth' && - integration.installIdentificationMethod === 'edge_function_secret_name' && - !!integration.edgeFunctionSecretName - ) - }, [allIntegrations]) - - const hasCallbackStatusIntegration = useMemo(() => { - return allIntegrations.some( - (integration) => - integration.type === 'oauth' && - integration.installIdentificationMethod === 'integration_status' - ) + const hasOAuthIntegration = useMemo(() => { + return allIntegrations.some((integration) => integration.type === 'oauth') }, [allIntegrations]) const { - data: apiKeys = EMPTY_ARR, - error: apiKeysError, - isError: isErrorApiKeys, - isLoading: isApiKeysLoading, - isSuccess: isSuccessApiKeys, - } = useAPIKeysQuery( - { projectRef: project?.ref, reveal: false }, - { enabled: hasSecretKeyPrefixIntegration } - ) - - const { - data: edgeFunctionSecrets = EMPTY_ARR, - error: edgeFunctionSecretsError, - isError: isErrorEdgeFunctionSecrets, - isLoading: isEdgeFunctionSecretsLoading, - isSuccess: isSuccessEdgeFunctionSecrets, - } = useSecretsQuery( - { projectRef: project?.ref }, - { enabled: hasEdgeFunctionSecretNameIntegration } - ) - - const { - data: partnerIntegrations = EMPTY_ARR, - error: partnerIntegrationsError, - isError: isErrorPartnerIntegrations, - isLoading: isPartnerIntegrationsLoading, - isSuccess: isSuccessPartnerIntegrations, - } = usePartnerIntegrationsQuery( - { projectRef: project?.ref }, - { enabled: hasCallbackStatusIntegration } - ) + data: oauthData, + error: oauthDataError, + isError: isErrorOAuthData, + isLoading: isOAuthDataLoading, + isSuccess: isSuccessOAuthData, + } = useProjectOAuthIntegrationData(project?.ref, { enabled: hasOAuthIntegration }) const { data: wrappers = EMPTY_ARR, @@ -137,48 +88,38 @@ export const useInstalledIntegrations = () => { if (integration.type === 'oauth') { return isOAuthInstalled({ integration, - apiKeys, - partnerIntegrations, - secrets: edgeFunctionSecrets, + projectData: oauthData, }) } return false }) .sort((a, b) => a.name.localeCompare(b.name)) - }, [allIntegrations, wrappers, extensions, schemas, isHooksEnabled, apiKeys, edgeFunctionSecrets]) + }, [allIntegrations, wrappers, extensions, schemas, isHooksEnabled, oauthData]) const error = fdwError || extensionsError || schemasError || availableIntegrationsError || - (hasSecretKeyPrefixIntegration ? apiKeysError : null) || - (hasEdgeFunctionSecretNameIntegration ? edgeFunctionSecretsError : null) || - (hasCallbackStatusIntegration ? partnerIntegrationsError : null) + (hasOAuthIntegration ? oauthDataError : null) const isLoading = isSchemasLoading || isFDWLoading || isExtensionsLoading || isAvailableIntegrationsLoading || - (hasSecretKeyPrefixIntegration && isApiKeysLoading) || - (hasEdgeFunctionSecretNameIntegration && isEdgeFunctionSecretsLoading) || - (hasCallbackStatusIntegration && isPartnerIntegrationsLoading) + (hasOAuthIntegration && isOAuthDataLoading) const isError = isErrorFDWs || isErrorExtensions || isErrorSchemas || isErrorAvailableIntegrations || - (hasSecretKeyPrefixIntegration && isErrorApiKeys) || - (hasEdgeFunctionSecretNameIntegration && isErrorEdgeFunctionSecrets) || - (hasCallbackStatusIntegration && isErrorPartnerIntegrations) + (hasOAuthIntegration && isErrorOAuthData) const isSuccess = isSuccessFDWs && isSuccessExtensions && isSuccessSchemas && isSuccessAvailableIntegrations && - (!hasSecretKeyPrefixIntegration || isSuccessApiKeys) && - (!hasEdgeFunctionSecretNameIntegration || isSuccessEdgeFunctionSecrets) && - (!hasCallbackStatusIntegration || isSuccessPartnerIntegrations) + (!hasOAuthIntegration || isSuccessOAuthData) return { // show all integrations at once instead of showing partial results diff --git a/packages/common/marketplace.types.ts b/packages/common/marketplace.types.ts index b2712607278..225f7370b9c 100644 --- a/packages/common/marketplace.types.ts +++ b/packages/common/marketplace.types.ts @@ -50,7 +50,7 @@ export type Database = { listing_logo: string | null listing_tsv: unknown marketplace_url: string | null - oauth_client_id: string | null + oauth_app_id: string | null partner_id: string | null partner_logo: string | null partner_name: string | null From 4eaef098fa4f053d90baa92b145f968836fca3f8 Mon Sep 17 00:00:00 2001 From: Charis <26616127+charislam@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:44:11 -0400 Subject: [PATCH 003/134] fix: auth config updates (#46683) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES/NO ## What kind of change does this PR introduce? Bug fix, feature, docs update, ... ## What is the current behavior? Please link any relevant issues here. ## What is the new behavior? Feel free to include screenshots if it includes visual changes. ## Additional context Add any other context or screenshots. ## Summary by CodeRabbit * **Bug Fixes** * Authentication configuration updates now trigger the app's default refresh behavior, ensuring changes propagate automatically and remain synchronized across the interface. --- apps/studio/data/auth/auth-config-update-mutation.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/studio/data/auth/auth-config-update-mutation.ts b/apps/studio/data/auth/auth-config-update-mutation.ts index 7d1fb426221..51f6ddc7577 100644 --- a/apps/studio/data/auth/auth-config-update-mutation.ts +++ b/apps/studio/data/auth/auth-config-update-mutation.ts @@ -1,7 +1,6 @@ import { useMutation, useQueryClient } from '@tanstack/react-query' import { toast } from 'sonner' -import type { ProjectAuthConfigData } from './auth-config-query' import { authKeys } from './keys' import type { components } from '@/data/api' import { handleError, patch } from '@/data/fetchers' @@ -46,10 +45,8 @@ export const useAuthConfigUpdateMutation = ({ const { projectRef, skipInvalidation = false } = variables if (!skipInvalidation) { - queryClient.setQueryData(authKeys.authConfig(projectRef), data) await queryClient.invalidateQueries({ queryKey: authKeys.authConfig(projectRef), - refetchType: 'none', }) } From b9f95c9aa9708061a5410807520671685b2c74cb Mon Sep 17 00:00:00 2001 From: Miranda Limonczenko <23711156+czenko@users.noreply.github.com> Date: Fri, 5 Jun 2026 15:00:32 -0700 Subject: [PATCH 004/134] fix(docs) Resolve React Router auth setup errors and confusion (#46684) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes DOCS-651 ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? This adds a non-null assertion to a Supabase method that expects non-null. Additionally, it updates a label from 'Remix' to 'React Router'. ## What is the current behavior? Two issues: - Following the Auth client steps with React Router creates a `deprecation` error and downstream Typescript errors. - 'Remix' is renamed to 'React Router'. > Remix and React Router are the same thing, made by the same people. Remix was simply renamed React Router Framework Mode starting in version 7 of React Router. - [Blog Source](https://reacttraining.com/blog/remix-vs-react-router-framework) Screenshot 2026-06-04 at 4 00 45 PM Screenshot 2026-06-05 at 11 21 54 AM ## What is the new behavior? - Adding a non-null assertion clears up all error. Running the application does not produce errors. - Changing the label from "Remix" to "React Router" updates the dropdown name to match the rebrand. Now, it does not look outdated and matches the docs. Screenshot 2026-06-05 at 11 22 48 AM ## Additional context The task was to clarify our documentation on this page: [Create a Client](https://supabase.com/docs/guides/auth/server-side/creating-a-client?queryGroups=framework&framework=react-router&queryGroups=environment&environment=react-router-loader#create-a-client) However, the code sample in the docs is correct; the documentation in **Dashboard** produced the errors. ## Future improvements - To make this more robust, the code could have a single source of truth. ## Summary by CodeRabbit * **Bug Fixes** * Clarified generated Supabase server client template text to improve type/reference safety in the Remix integration guide. * **UI** * Renamed framework label from "Remix" to "React Router" across the Connect interfaces for clearer framework identification. --------- Co-authored-by: Miranda Limonczenko --- apps/studio/components/interfaces/Connect/Connect.constants.ts | 2 +- .../interfaces/Connect/content/remix/supabasejs/content.tsx | 2 +- .../components/interfaces/ConnectSheet/Connect.constants.ts | 2 +- .../ConnectSheet/content/remix/supabasejs/content.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/studio/components/interfaces/Connect/Connect.constants.ts b/apps/studio/components/interfaces/Connect/Connect.constants.ts index 07854fdfb18..6b71f1e8229 100644 --- a/apps/studio/components/interfaces/Connect/Connect.constants.ts +++ b/apps/studio/components/interfaces/Connect/Connect.constants.ts @@ -109,7 +109,7 @@ export const FRAMEWORKS: ConnectionType[] = [ }, { key: 'remix', - label: 'Remix', + label: 'React Router', icon: 'remix', guideLink: `${DOCS_URL}/guides/auth/server-side/creating-a-client?framework=remix&environment=remix-loader`, children: [ diff --git a/apps/studio/components/interfaces/Connect/content/remix/supabasejs/content.tsx b/apps/studio/components/interfaces/Connect/content/remix/supabasejs/content.tsx index 58ab3a1a907..8f65ce355d2 100644 --- a/apps/studio/components/interfaces/Connect/content/remix/supabasejs/content.tsx +++ b/apps/studio/components/interfaces/Connect/content/remix/supabasejs/content.tsx @@ -44,7 +44,7 @@ export function createClient(request: Request) { const supabase = createServerClient( process.env.VITE_SUPABASE_URL!, - process.env.VITE_${projectKeys.publishableKey ? 'SUPABASE_PUBLISHABLE_KEY' : 'SUPABASE_ANON_KEY'};, + process.env.VITE_${projectKeys.publishableKey ? 'SUPABASE_PUBLISHABLE_KEY' : 'SUPABASE_ANON_KEY'}!, { cookies: { getAll() { diff --git a/apps/studio/components/interfaces/ConnectSheet/Connect.constants.ts b/apps/studio/components/interfaces/ConnectSheet/Connect.constants.ts index b1f9f1a6d50..2d7673555a0 100644 --- a/apps/studio/components/interfaces/ConnectSheet/Connect.constants.ts +++ b/apps/studio/components/interfaces/ConnectSheet/Connect.constants.ts @@ -109,7 +109,7 @@ export const FRAMEWORKS: ConnectionType[] = [ }, { key: 'remix', - label: 'Remix', + label: 'React Router', icon: 'remix', guideLink: `${DOCS_URL}/guides/auth/server-side/creating-a-client?framework=remix&environment=remix-loader`, children: [ diff --git a/apps/studio/components/interfaces/ConnectSheet/content/remix/supabasejs/content.tsx b/apps/studio/components/interfaces/ConnectSheet/content/remix/supabasejs/content.tsx index 3b3786fae13..d2eada2353e 100644 --- a/apps/studio/components/interfaces/ConnectSheet/content/remix/supabasejs/content.tsx +++ b/apps/studio/components/interfaces/ConnectSheet/content/remix/supabasejs/content.tsx @@ -30,7 +30,7 @@ export function createClient(request: Request) { const supabase = createServerClient( process.env.VITE_SUPABASE_URL!, - process.env.VITE_${projectKeys.publishableKey ? 'SUPABASE_PUBLISHABLE_KEY' : 'SUPABASE_ANON_KEY'}, + process.env.VITE_${projectKeys.publishableKey ? 'SUPABASE_PUBLISHABLE_KEY' : 'SUPABASE_ANON_KEY'}!, { cookies: { getAll() { From 3e3496ef6c395b60bf90d0266e77751919443682 Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Fri, 5 Jun 2026 18:10:49 -0400 Subject: [PATCH 005/134] fix(studio): copy updates to revoke oauth modal (#46687) --- .../Organization/OAuthApps/RevokeAppModal.tsx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/apps/studio/components/interfaces/Organization/OAuthApps/RevokeAppModal.tsx b/apps/studio/components/interfaces/Organization/OAuthApps/RevokeAppModal.tsx index f46e0e4d037..bdf097b0d95 100644 --- a/apps/studio/components/interfaces/Organization/OAuthApps/RevokeAppModal.tsx +++ b/apps/studio/components/interfaces/Organization/OAuthApps/RevokeAppModal.tsx @@ -40,13 +40,13 @@ export const RevokeAppModal = ({ selectedApp, onClose }: RevokeAppModalProps) => - {`Confirm to revoke ${selectedApp?.name}`} + {`Revoke access for ${selectedApp?.name}?`}
    @@ -56,8 +56,15 @@ export const RevokeAppModal = ({ selectedApp, onClose }: RevokeAppModalProps) => Before you remove this app, consider:
    • - No users are currently using this application. The application will no - longer have access to your organization after being revoked. + The application will no longer have access to your organization after being + revoked. +
    • +
    • + This will remove the application for all members in your organization. +
    • +
    • + Restoring access will require an organization administrator to re-authorize + the application.
From 8af2bb0cda6fee344242b5ed31eb99b4392715e5 Mon Sep 17 00:00:00 2001 From: Eduardo Gurgel Date: Mon, 8 Jun 2026 14:13:34 +1200 Subject: [PATCH 006/134] docs: document binary broadcast messages (#46668) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Document Realtime broadcast of binary payloads ## Summary by CodeRabbit * **Documentation** * Clarified binary payload behavior across SDKs and runtimes, including version-gated support and which clients silently drop binaries. * Added examples for sending binary messages via JavaScript, Swift, REST (including file upload), and database broadcasts. * Clarified REST payload handling (Content-Type selects JSON vs binary), private messaging flag, and that batch endpoints accept JSON-only. * Noted that channel.httpSend() uses REST starting in supabase-js 2.107.0. Co-authored-by: Chris Chinchilla --- .../content/guides/realtime/broadcast.mdx | 121 +++++++++++++----- 1 file changed, 90 insertions(+), 31 deletions(-) diff --git a/apps/docs/content/guides/realtime/broadcast.mdx b/apps/docs/content/guides/realtime/broadcast.mdx index a6f73498569..6714da11eca 100644 --- a/apps/docs/content/guides/realtime/broadcast.mdx +++ b/apps/docs/content/guides/realtime/broadcast.mdx @@ -128,6 +128,12 @@ Get the Project URL and key from [the project's **Connect** dialog](/dashboard/p You can receive Broadcast messages by providing a callback to the channel. + + +Binary payloads (`ArrayBuffer` / `ArrayBufferView`) are received automatically from **supabase-js 2.91.0** and **supabase-swift 2.44.0**. On older SDK versions, binary messages are silently dropped and never reach the callback. + + + + +Broadcast payloads can be binary (`ArrayBuffer` or `ArrayBufferView`, e.g. `Uint8Array`) over WebSocket from **supabase-js 2.91.0** and **supabase-swift 2.44.0**. Binary payloads sent to clients running older SDK versions are **silently dropped** and never arrive over the WebSocket. The Dart, Kotlin, and Python clients don't support binary payloads yet. + + + @@ -335,6 +357,12 @@ You can use the Supabase client libraries to send Broadcast messages. <$Show if="sdk:swift"> + + + Binary payloads over WebSocket are supported from supabase-swift 2.44.0. Receivers on older SDK versions will not get binary messages. + + + {/* prettier-ignore */} ```swift let myChannel = await supabase.channel("test-channel") { @@ -440,11 +468,31 @@ By default, all database broadcasts are private, meaning clients must authentica +To broadcast a binary payload from your database, use the `realtime.send_binary()` function with a `bytea` payload: + +{/* prettier-ignore */} +```sql +select + realtime.send_binary( + '\x012345'::bytea, -- bytea payload + 'event', -- Event name + 'topic', -- Topic + true -- Private / Public flag (defaults to true) + ); +``` + +The same public/private matching rule applies: a binary broadcast only reaches channels with the same private setting. Binary messages only reach clients on **supabase-js 2.91.0** and **supabase-swift 2.44.0** or later; older clients silently drop them. + You can use the `realtime.broadcast_changes()` helper function to broadcast messages when a record is created, updated, or deleted. For more details, read [Subscribing to Database Changes](/docs/guides/realtime/subscribing-to-database-changes). ### Broadcast using the REST API -You can send a Broadcast message by making an HTTP request to Realtime servers. +You can send a single Broadcast message by making an HTTP request to Realtime servers. The endpoint embeds the topic and event in the path, and the `Content-Type` header determines the payload type: + +- `application/json` — JSON payload +- `application/octet-stream` — binary payload + +Add `?private=true` to broadcast to a private channel. ' \ -H 'Content-Type: application/json' \ - --data-raw '{ - "messages": [ - { - "topic": "test", - "event": "event", - "payload": { "test": "test" } - } - ] - }' \ - 'https://.supabase.co/realtime/v1/api/broadcast' + --data-raw '{ "test": "test" }' \ + 'https://.supabase.co/realtime/v1/api/broadcast/test/events/event' + + # Binary payload + curl -v \ + -H 'apikey: ' \ + -H 'Content-Type: application/octet-stream' \ + --data-binary @payload.bin \ + 'https://.supabase.co/realtime/v1/api/broadcast/test/events/event?private=true' ``` @@ -477,26 +525,39 @@ You can send a Broadcast message by making an HTTP request to Realtime servers. {/* prettier-ignore */} ```bash - POST /realtime/v1/api/broadcast HTTP/1.1 + POST /realtime/v1/api/broadcast/test/events/event HTTP/1.1 Host: {PROJECT_REF}.supabase.co Content-Type: application/json apikey: {SUPABASE_TOKEN} - { - "messages": [ - { - "topic": "test", - "event": "event", - "payload": { - "test": "test" - } - } - ] - } + { "test": "test" } ``` + + +To send multiple messages in a single request, the batch endpoint `POST /realtime/v1/api/broadcast` is still available. It accepts a JSON body with a `messages` array (JSON payloads only): + +{/* prettier-ignore */} +```bash +curl -v \ +-H 'apikey: ' \ +-H 'Content-Type: application/json' \ +--data-raw '{ + "messages": [ + { + "topic": "test", + "event": "event", + "payload": { "test": "test" } + } + ] +}' \ +'https://.supabase.co/realtime/v1/api/broadcast' +``` + + + ## Broadcast options You can pass configuration options while initializing the Supabase Client. @@ -783,7 +844,7 @@ You can also send a Broadcast message by making an HTTP request to Realtime serv - This is currently available only in the Supabase JavaScript client version 2.37.0 and later. + `channel.httpSend()` always uses the REST API regardless of WebSocket connection state, and is available from the Supabase JavaScript client version 2.107.0 and later. `ArrayBuffer` and `ArrayBufferView` (e.g. `Uint8Array`) payloads are sent as `application/octet-stream`; all other payloads are JSON-encoded. @@ -792,13 +853,11 @@ You can also send a Broadcast message by making an HTTP request to Realtime serv // No need to subscribe to channel - channel - .send({ - type: 'broadcast', - event: 'test', - payload: { message: 'Hi' }, - }) - .then((resp) => console.log(resp)) + // JSON payload + await channel.httpSend('cursor-pos', { x: Math.random(), y: Math.random() }) + + // Binary payload (ArrayBuffer / ArrayBufferView) — sent as application/octet-stream + await channel.httpSend('cursor-pos', new Uint8Array([1, 2, 3]).buffer) // Remember to clean up the channel From a2300700d918e73e9a6c4578ca62780bdd2bb3ac Mon Sep 17 00:00:00 2001 From: lch-supa Date: Mon, 8 Jun 2026 03:52:00 -0400 Subject: [PATCH 007/134] docs: Remove unexposed extensions (#46686) removes three extensions from the list on the Postgres Extensions docs page because we do not expose those extensions to users. extensions removed are: amcheck, pg_surgery, pg_freespacemap also adds a small cosmetic change to clarify that "public" refers to the `public` schema on the same documentation page ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? docs update ## What is the current behavior? extensions are listed at https://supabase.com/docs/guides/database/extensions that will result in permissions errors should users try to install them themselves, as they require superuser access to install ## What is the new behavior? removes those items from the list ## Additional context ## Summary by CodeRabbit * **Documentation** * Updated extensions overview documentation with improved formatting for better readability * **Chores** * Removed three extensions from the available extensions metadata --- .../content/guides/database/extensions.mdx | 2 +- packages/shared-data/extensions.json | 27 ------------------- 2 files changed, 1 insertion(+), 28 deletions(-) diff --git a/apps/docs/content/guides/database/extensions.mdx b/apps/docs/content/guides/database/extensions.mdx index e7e090c6ad4..0c4dee671b3 100644 --- a/apps/docs/content/guides/database/extensions.mdx +++ b/apps/docs/content/guides/database/extensions.mdx @@ -44,7 +44,7 @@ To disable an extension call `drop extension`. -Most extensions are installed under the `extensions` schema, which is accessible to public by default. To avoid namespace pollution, we do not recommend creating other entities in the `extensions` schema. +Most extensions are installed under the `extensions` schema, which is accessible to `public` by default. To avoid namespace pollution, we do not recommend creating other entities in the `extensions` schema. If you need to restrict user access to tables managed by extensions, we recommend creating a separate schema for installing that specific extension. diff --git a/packages/shared-data/extensions.json b/packages/shared-data/extensions.json index b2788fabaea..c219fd1913a 100644 --- a/packages/shared-data/extensions.json +++ b/packages/shared-data/extensions.json @@ -17,15 +17,6 @@ "product": null, "product_url": null }, - { - "name": "amcheck", - "comment": "functions for verifying relation integrity", - "tags": ["Admin", "Utility"], - "link": "https://www.postgresql.org/docs/current/amcheck.html", - "github_url": null, - "product": null, - "product_url": null - }, { "name": "autoinc", "comment": "functions for autoincrementing fields", @@ -233,15 +224,6 @@ "product": "Supabase Cron", "product_url": "/project/{ref}/integrations/cron" }, - { - "name": "pg_freespacemap", - "comment": "examine the free space map (FSM)", - "tags": ["Admin", "Utility"], - "link": "https://www.postgresql.org/docs/current/pgfreespacemap.html", - "github_url": null, - "product": null, - "product_url": null - }, { "name": "pg_graphql", "comment": "pg_graphql: GraphQL support", @@ -305,15 +287,6 @@ "product": "Query Performance", "product_url": "/project/{ref}/observability/query-performance" }, - { - "name": "pg_surgery", - "comment": "extension to perform surgery on a damaged relation", - "tags": ["Admin", "Utility"], - "link": "https://www.postgresql.org/docs/current/pgsurgery.html", - "github_url": null, - "product": null, - "product_url": null - }, { "name": "pg_trgm", "comment": "text similarity measurement and index searching based on trigrams", From caf2c2c00cf4fbca39d227e1b10a5764aa3c6f36 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Mon, 8 Jun 2026 13:37:43 +0530 Subject: [PATCH 008/134] fix: wrappers link when marketplace feature preview is enabled (#46718) In the new marketplace revamped view the link to filter wrappers should be `/project/_/integrations?type=wrapper` instead of the old `/project/_/integrations?category=wrapper`. This PR fixes the broken link when the marketplace feature preview is enabled. ## Summary by CodeRabbit * **Bug Fixes** * Wrappers menu item now routes correctly when different marketplace page variants are enabled. --- .../layouts/DatabaseLayout/DatabaseMenu.utils.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/apps/studio/components/layouts/DatabaseLayout/DatabaseMenu.utils.tsx b/apps/studio/components/layouts/DatabaseLayout/DatabaseMenu.utils.tsx index f8f93ed79a6..d110a2ceee5 100644 --- a/apps/studio/components/layouts/DatabaseLayout/DatabaseMenu.utils.tsx +++ b/apps/studio/components/layouts/DatabaseLayout/DatabaseMenu.utils.tsx @@ -1,7 +1,10 @@ import { useParams } from 'common' import { ArrowUpRight } from 'lucide-react' -import { useIsColumnLevelPrivilegesEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' +import { + useIsColumnLevelPrivilegesEnabled, + useIsMarketplaceEnabled, +} from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { useIsETLPrivateAlpha } from '@/components/interfaces/Database/Replication/useIsETLPrivateAlpha' import type { ProductMenuGroup, @@ -39,6 +42,12 @@ export const useGenerateDatabaseMenu = (): ProductMenuGroup[] => { const getDatabaseURL = (path: string) => `/project/${ref}/database/${path}` + // In the new marketplace revamped page the `category=wrapper` query param has + // changed to `type=wrapper`. So fix this link below based on which version is + // the user viewing. + const isMarketplaceEnabled = useIsMarketplaceEnabled() + const wrappersLinkParamName = isMarketplaceEnabled ? 'type' : 'category' + return [ { title: 'Database Management', @@ -148,7 +157,7 @@ export const useGenerateDatabaseMenu = (): ProductMenuGroup[] => { showWrappers && { name: 'Wrappers', key: 'wrappers', - url: `/project/${ref}/integrations?category=wrapper`, + url: `/project/${ref}/integrations?${wrappersLinkParamName}=wrapper`, rightIcon: ExternalLinkIcon, }, pgNetExtensionExists && { From 188ae5333318016e1b010a88241d9fa45921001f Mon Sep 17 00:00:00 2001 From: Francesco Sansalvadore Date: Mon, 8 Jun 2026 10:48:54 +0200 Subject: [PATCH 009/134] fix(studio): new wrapper form closing bug (#46698) When trying to create a new wrapper from the integrations page and no wrappers exist yet, then the sheet is not closable unless you submit the form or refresh the page. https://github.com/user-attachments/assets/7d46cce3-0a0f-4efd-ba98-d141cfcfe31c ## After - The sheet is closable with confirmation modal - added nuqs to open "new" wrapper form via `new=true` params https://github.com/user-attachments/assets/36c4ae9e-7aa8-430c-9741-6d84978997f1 ## Summary by CodeRabbit * **Refactor** * Improved state management for the wrapper creation dialog, enabling state persistence through URL parameters for better shareability and navigation consistency. --- .../Integrations/Wrappers/WrappersTab.tsx | 109 +++++++++--------- 1 file changed, 53 insertions(+), 56 deletions(-) diff --git a/apps/studio/components/interfaces/Integrations/Wrappers/WrappersTab.tsx b/apps/studio/components/interfaces/Integrations/Wrappers/WrappersTab.tsx index aec304ece77..c52a6df134c 100644 --- a/apps/studio/components/interfaces/Integrations/Wrappers/WrappersTab.tsx +++ b/apps/studio/components/interfaces/Integrations/Wrappers/WrappersTab.tsx @@ -1,6 +1,7 @@ import { PermissionAction } from '@supabase/shared-types/out/constants' import { useParams } from 'common' -import { HTMLProps, ReactNode, useCallback, useState } from 'react' +import { parseAsBoolean, useQueryState } from 'nuqs' +import { useCallback, useState } from 'react' import { Sheet, SheetContent } from 'ui' import { CreateWrapperSheet } from './CreateWrapperSheet' @@ -20,14 +21,18 @@ import { useShortcut } from '@/state/shortcuts/useShortcut' export const WrappersTab = () => { const { id } = useParams() const { data: project } = useSelectedProjectQuery() - const [createWrapperShown, setCreateWrapperShown] = useState(false) + + const [isCreating, setIsCreating] = useQueryState( + 'new', + parseAsBoolean.withDefault(false).withOptions({ clearOnDefault: true }) + ) const { can: canCreateWrapper } = useAsyncCheckPermissions( PermissionAction.TENANT_SQL_ADMIN_WRITE, 'wrappers' ) - useShortcut(SHORTCUT_IDS.LIST_PAGE_NEW_ITEM, () => setCreateWrapperShown(true), { + useShortcut(SHORTCUT_IDS.LIST_PAGE_NEW_ITEM, () => setIsCreating(true), { label: 'Add new wrapper', enabled: canCreateWrapper, }) @@ -40,7 +45,6 @@ export const WrappersTab = () => { const wrappers = data ?? [] const wrapperMeta = WRAPPERS.find((w) => w.name === id) - // this contains a collection of all wrapper instances for the wrapper type const createdWrappers = wrapperMeta ? wrappers.filter((w) => wrapperMetaComparator(wrapperMeta, w)) : [] @@ -49,47 +53,26 @@ export const WrappersTab = () => { const { confirmOnClose, handleOpenChange, modalProps } = useConfirmOnClose({ checkIsDirty: useCallback(() => isDirty, [isDirty]), onClose: useCallback(() => { - setCreateWrapperShown(false) + setIsCreating(null) setIsDirty(false) - }, []), + }, [setIsCreating]), }) - const Container = useCallback( - ({ ...props }: { children: ReactNode } & HTMLProps) => ( -
- {props.children} - - - {wrapperMeta && ( - setCreateWrapperShown(false)} - onCloseWithConfirmation={confirmOnClose} - /> - )} - - -
- ), - [createWrapperShown, handleOpenChange, wrapperMeta, confirmOnClose] - ) - if (!wrapperMeta) { return
Missing integration.
} - if (createdWrappers.length === 0) { - return ( - -
+ return ( +
+ {createdWrappers.length === 0 ? ( +

No {wrapperMeta.label} wrappers have been installed

setCreateWrapperShown(true)} + onClick={() => setIsCreating(true)} disabled={!canCreateWrapper} tooltip={{ content: { @@ -103,31 +86,45 @@ export const WrappersTab = () => {
- - ) - } + ) : ( +
+ + setIsCreating(true)} + disabled={!canCreateWrapper} + tooltip={{ + content: { + text: !canCreateWrapper + ? 'You need additional permissions to create a foreign data wrapper' + : undefined, + }, + }} + > + Add new wrapper + +
+ )} + + {createdWrappers.length > 0 && } + + + + {wrapperMeta && ( + { + setIsCreating(null) + setIsDirty(false) + }} + onCloseWithConfirmation={confirmOnClose} + /> + )} + + - return ( - -
- - setCreateWrapperShown(true)} - disabled={!canCreateWrapper} - tooltip={{ - content: { - text: !canCreateWrapper - ? 'You need additional permissions to create a foreign data wrapper' - : undefined, - }, - }} - > - Add new wrapper - -
- -
+
) } From c713508fce06e04442393a2ac1162d287c30df7a Mon Sep 17 00:00:00 2001 From: Hieu Date: Mon, 8 Jun 2026 16:12:17 +0700 Subject: [PATCH 010/134] fix: check token.scope for access resource display (#46603) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Bug fix ## What is the current behavior? Scoped PAT access message checks `organization_slugs`/`project_refs` to determine display text. This breaks when an org/project is deleted; its tuple is removed and consequently from the token's slugs/refs, causing a scoped token to incorrectly show "This token has access to all resources." ## What is the new behavior? Check the `token.scope` directly: - `user` → "This token has access to all resources." - `organization` → "This token has access to specific organizations." (or "This token has no accessible organizations." if all scoped orgs were removed) - `project` → "This token has access to specific projects." (or "This token has no accessible projects." if all scoped projects were removed) ## Summary by CodeRabbit * **Bug Fixes** * Improved clarity of access token scope messaging. The resource access information now displays more specific and accurate details based on token type, distinguishing between organization-level, project-level, and user-level access permissions. --- .../AccessTokens/Scoped/ViewTokenSheet.tsx | 15 ++++++++++----- packages/api-types/types/platform.d.ts | 2 ++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/apps/studio/components/interfaces/Account/AccessTokens/Scoped/ViewTokenSheet.tsx b/apps/studio/components/interfaces/Account/AccessTokens/Scoped/ViewTokenSheet.tsx index 8ca78ea879c..e3a6a51075c 100644 --- a/apps/studio/components/interfaces/Account/AccessTokens/Scoped/ViewTokenSheet.tsx +++ b/apps/studio/components/interfaces/Account/AccessTokens/Scoped/ViewTokenSheet.tsx @@ -231,11 +231,16 @@ export function ViewTokenSheet({ visible, tokenId, onClose }: ViewTokenSheetProp

- {(token?.organization_slugs && - token.organization_slugs.length > 0) || - (token?.project_refs && token.project_refs.length > 0) - ? 'This token has access to specific organizations and projects.' - : 'This token has access to all resources.'} + {token?.scope === 'organization' + ? token.organization_slugs && + token.organization_slugs.length > 0 + ? 'This token has access to specific organizations.' + : 'This token has no accessible organizations.' + : token?.scope === 'project' + ? token.project_refs && token.project_refs.length > 0 + ? 'This token has access to specific projects.' + : 'This token has no accessible projects.' + : 'This token has access to all resources.'}

diff --git a/packages/api-types/types/platform.d.ts b/packages/api-types/types/platform.d.ts index 08ebaa05eb8..ba5359d3206 100644 --- a/packages/api-types/types/platform.d.ts +++ b/packages/api-types/types/platform.d.ts @@ -7031,6 +7031,8 @@ export interface components { organization_slugs?: string[] permissions: string[] project_refs?: string[] + /** @enum {string} */ + scope: 'user' | 'organization' | 'project' token_alias: string } GetScopedAccessTokensResponse: { From ab93452cdfc0fd0d840eb0a94e1622be48425526 Mon Sep 17 00:00:00 2001 From: Jordi Enric <37541088+jordienr@users.noreply.github.com> Date: Mon, 8 Jun 2026 11:31:47 +0200 Subject: [PATCH 011/134] fix(unified-logs): apply sidebar facet filters on click (#46589) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problem Clicking a checkbox in the logs filter sidebar (Log Type, Status, Method, etc.) doesn't do anything. The box ticks, but the log list and counts don't change. Only the search bar at the top actually filters. On top of that, opening a URL that already has filters renders the sidebar checkboxes unticked, so the active filters are invisible. ## Solution The top search bar and the sidebar each store a selected filter in a different internal format. A recent change taught the query builder (`columnFiltersToLogsFilters`) to understand only the search bar's wrapped `{ operator, values }` format, so anything clicked in the sidebar (a bare `string[]`) was thrown away before it reached the query, and nothing refetched. - Accept the sidebar's bare format, treating it as a plain "equals" filter (which is exactly what a checkbox means). Sidebar clicks apply immediately again. - Seed the sidebar checkboxes from the URL: equality filter groups are seeded as a bare `string[]` (the shape the checkbox reads), so they render ticked on load. Non-eq groups (neq/ilike from the top bar) stay wrapped so their operator survives a round-trip. - Keep the time-range picker out of the `filter` URL param so it doesn't get swept in by mistake. - Extracted the URL-building (`buildFilterSearchUpdate`) and URL-seeding (`logsFiltersToColumnFilters`) into pure helpers so the click-to-query and URL-load wiring are unit tested, not just the transform. ## How to test Open Unified Logs and click a Log Type / Status / Method checkbox in the left sidebar. The list and counts should update right away, without touching the top search bar. Reload the page (or open a shared URL with filters): the matching sidebar checkboxes should be ticked. `UnifiedLogs.filters.test.ts` covers both filter formats, the time-range exclusion, cleared filters, the click-to-URL wiring, and the URL-load round-trip (including that a neq filter is not downgraded to eq). ## Summary by CodeRabbit * **Tests** * Added coverage for filter ↔ URL conversions, checkbox grouping, operator preservation, null/cleared handling, and timerange routing. * **Bug Fixes** * Consistently normalize and serialize varied filter input shapes. * Omit non-allowlisted columns from URL filters. * Ensure timerange uses its dedicated URL key and is removed when cleared. * **Refactor** * Centralized filter serialization/deserialization and simplified URL update wiring. --------- Co-authored-by: Claude Opus 4.8 --- .../UnifiedLogs/UnifiedLogs.filters.test.ts | 124 ++++++++++++++++++ .../UnifiedLogs/UnifiedLogs.filters.ts | 44 ++++++- .../interfaces/UnifiedLogs/UnifiedLogs.tsx | 27 +--- 3 files changed, 168 insertions(+), 27 deletions(-) create mode 100644 apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.filters.test.ts diff --git a/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.filters.test.ts b/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.filters.test.ts new file mode 100644 index 00000000000..68538d1680d --- /dev/null +++ b/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.filters.test.ts @@ -0,0 +1,124 @@ +import { describe, expect, it } from 'vitest' + +import { + buildFilterSearchUpdate, + columnFiltersToLogsFilters, + logsFiltersToColumnFilters, + logsFiltersToUrlParams, + parseLogsFilterUrlParams, +} from './UnifiedLogs.filters' + +describe('columnFiltersToLogsFilters', () => { + it('serializes a bare string[] (sidebar checkbox) using the default `=` operator', () => { + const filters = columnFiltersToLogsFilters([ + { id: 'log_type', value: ['postgres', 'postgrest'] }, + ]) + expect(filters).toEqual([ + { column: 'log_type', operator: '=', value: 'postgres' }, + { column: 'log_type', operator: '=', value: 'postgrest' }, + ]) + expect(logsFiltersToUrlParams(filters)).toEqual([ + 'log_type:eq:postgres', + 'log_type:eq:postgrest', + ]) + }) + + it('preserves the operator from a wrapped value (top filter bar)', () => { + const filters = columnFiltersToLogsFilters([ + { id: 'method', value: { operator: '<>', values: ['GET'] } }, + ]) + expect(filters).toEqual([{ column: 'method', operator: '<>', value: 'GET' }]) + }) + + it('treats a bare non-array scalar as a single `=` value', () => { + const filters = columnFiltersToLogsFilters([{ id: 'status', value: '500' }]) + expect(filters).toEqual([{ column: 'status', operator: '=', value: '500' }]) + }) + + it('excludes columns not in filterableNames (e.g. the `date` timerange brush)', () => { + const filterable = new Set(['log_type', 'method']) + const filters = columnFiltersToLogsFilters( + [ + { id: 'date', value: [new Date('2026-05-08T00:00:00Z'), new Date('2026-05-08T01:00:00Z')] }, + { id: 'log_type', value: ['postgres'] }, + ], + filterable + ) + expect(filters).toEqual([{ column: 'log_type', operator: '=', value: 'postgres' }]) + }) + + it('skips null/undefined values (cleared filters)', () => { + const filters = columnFiltersToLogsFilters([ + { id: 'log_type', value: null }, + { id: 'method', value: undefined }, + ]) + expect(filters).toEqual([]) + }) +}) + +describe('logsFiltersToColumnFilters', () => { + it('seeds an `=` group as a bare string[] so sidebar checkboxes render ticked', () => { + const columnFilters = logsFiltersToColumnFilters([ + { column: 'log_type', operator: '=', value: 'postgres' }, + { column: 'log_type', operator: '=', value: 'postgrest' }, + ]) + expect(columnFilters).toEqual([{ id: 'log_type', value: ['postgres', 'postgrest'] }]) + }) + + it('keeps non-eq groups wrapped so the operator survives a round-trip', () => { + const columnFilters = logsFiltersToColumnFilters([ + { column: 'event_message', operator: '~~*', value: 'error' }, + ]) + expect(columnFilters).toEqual([ + { id: 'event_message', value: { operator: '~~*', values: ['error'] } }, + ]) + }) + + it('round-trips an eq URL filter back to the same param without flipping the operator', () => { + const seeded = logsFiltersToColumnFilters(parseLogsFilterUrlParams(['method:eq:GET'])) + const update = buildFilterSearchUpdate(seeded, [{ value: 'method', type: 'checkbox' }]) + expect(update.filter).toEqual(['method:eq:GET']) + }) + + it('round-trips a neq URL filter without downgrading it to eq', () => { + const seeded = logsFiltersToColumnFilters(parseLogsFilterUrlParams(['method:neq:GET'])) + const update = buildFilterSearchUpdate(seeded, [{ value: 'method', type: 'checkbox' }]) + expect(update.filter).toEqual(['method:neq:GET']) + }) +}) + +describe('buildFilterSearchUpdate', () => { + const fields = [ + { value: 'date', type: 'timerange' }, + { value: 'log_type', type: 'checkbox' }, + { value: 'method', type: 'checkbox' }, + ] + + it('serializes a bare sidebar checkbox into the `filter` param (the regression)', () => { + const update = buildFilterSearchUpdate([{ id: 'log_type', value: ['postgres'] }], fields) + expect(update.filter).toEqual(['log_type:eq:postgres']) + }) + + it('clears the `filter` param to null when no equality filters are set', () => { + const update = buildFilterSearchUpdate([{ id: 'log_type', value: null }], fields) + expect(update.filter).toBeNull() + }) + + it('routes a timerange to its own URL key, never into `filter`', () => { + const range = [new Date('2026-05-08T00:00:00Z'), new Date('2026-05-08T01:00:00Z')] + const update = buildFilterSearchUpdate( + [ + { id: 'date', value: range }, + { id: 'method', value: ['GET'] }, + ], + fields + ) + expect(update.filter).toEqual(['method:eq:GET']) + expect(update.date).toBe(range) + }) + + it('nulls an absent timerange key so a cleared brush is removed from the URL', () => { + const update = buildFilterSearchUpdate([{ id: 'method', value: ['GET'] }], fields) + expect(update.date).toBeNull() + }) +}) diff --git a/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.filters.ts b/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.filters.ts index e327798e678..32614bf9088 100644 --- a/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.filters.ts +++ b/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.filters.ts @@ -81,15 +81,51 @@ export const groupLogsFiltersByColumn = ( return grouped } +export const logsFiltersToColumnFilters = ( + filters: LogsFilter[] +): { id: string; value: string[] | LogsColumnFilterValue }[] => { + return Object.entries(groupLogsFiltersByColumn(filters)).map(([id, group]) => + group.operator === '=' ? { id, value: group.values } : { id, value: group } + ) +} + export const columnFiltersToLogsFilters = ( - columnFilters: { id: string; value: unknown }[] + columnFilters: { id: string; value: unknown }[], + filterableNames?: Set ): LogsFilter[] => { const filters: LogsFilter[] = [] for (const { id, value } of columnFilters) { - if (!isLogsFilterColumnValue(value)) continue - for (const v of value.values) { - filters.push({ column: id, operator: value.operator, value: String(v) }) + if (filterableNames && !filterableNames.has(id)) continue + if (value === null || value === undefined) continue + const fallback: LogsColumnFilterValue = { + operator: '=', + values: (Array.isArray(value) ? value : [value]).map(String), + } + const { operator, values } = isLogsFilterColumnValue(value) ? value : fallback + for (const v of values) { + filters.push({ column: id, operator, value: v }) } } return filters } + +export const buildFilterSearchUpdate = ( + columnFilters: { id: string; value: unknown }[], + filterFields: { value: string; type: string }[] +): Record => { + const filterableNames = new Set( + filterFields.filter((field) => field.type !== 'timerange').map((field) => field.value) + ) + const filterEntries = logsFiltersToUrlParams( + columnFiltersToLogsFilters(columnFilters, filterableNames) + ) + const update: Record = { + filter: filterEntries.length > 0 ? filterEntries : null, + } + for (const field of filterFields) { + if (field.type !== 'timerange') continue + const current = columnFilters.find((c) => c.id === field.value)?.value + update[field.value] = current ?? null + } + return update +} diff --git a/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.tsx b/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.tsx index 58884413e67..a04be8fa290 100644 --- a/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.tsx +++ b/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.tsx @@ -39,9 +39,8 @@ import { ServiceFlowPanel } from './ServiceFlowPanel' import { SEARCH_PARAMS_PARSER } from './UnifiedLogs.constants' import { filterFields as defaultFilterFields } from './UnifiedLogs.fields' import { - columnFiltersToLogsFilters, - groupLogsFiltersByColumn, - logsFiltersToUrlParams, + buildFilterSearchUpdate, + logsFiltersToColumnFilters, parseLogsFilterUrlParams, } from './UnifiedLogs.filters' import { useLiveMode, useResetFocus } from './UnifiedLogs.hooks' @@ -92,12 +91,7 @@ export const UnifiedLogs = () => { const defaultColumnSorting = search.sort ? [search.sort] : [] const defaultColumnVisibility = { uuid: false } - // Column filters are seeded from the repeatable `filter` URL param. Each entry - // (`col:opAbbrev:value`) is grouped per column into a wrapped { operator, values } - // shape that the query builder reads back. - const defaultColumnFilters = Object.entries( - groupLogsFiltersByColumn(parseLogsFilterUrlParams(search.filter)) - ).map(([id, value]) => ({ id, value })) + const defaultColumnFilters = logsFiltersToColumnFilters(parseLogsFilterUrlParams(search.filter)) const [topBarHeight, setTopBarHeight] = useState(0) const topBarRef = useRef(null) @@ -294,21 +288,8 @@ export const UnifiedLogs = () => { }) }, [facets]) - // Debounced filter application to avoid too many API calls when user clicks multiple filters quickly. - // All equality/pattern column filters serialize into the repeatable `filter` URL param. Slider/timerange - // column filters keep their dedicated per-column URL keys so things like the timeline brush still - // round-trip — they have their own range semantics and aren't covered by eq/neq/like. const applyFilterSearch = () => { - const filterEntries = logsFiltersToUrlParams(columnFiltersToLogsFilters(columnFilters)) - const update: Record = { - filter: filterEntries.length > 0 ? filterEntries : null, - } - for (const field of filterFields) { - if (field.type !== 'timerange') continue - const current = columnFilters.find((c) => c.id === field.value)?.value - update[field.value] = current ?? null - } - setSearch(update) + setSearch(buildFilterSearchUpdate(columnFilters, filterFields)) } const debouncedApplyFilterSearch = useDebounce(applyFilterSearch, 250) From d745036c9e787aefb37e7aad7a5d496745611a0b Mon Sep 17 00:00:00 2001 From: ChloeGarciaMillerand Date: Mon, 8 Jun 2026 11:53:29 +0200 Subject: [PATCH 012/134] chore: create index form (#46288) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Refactored the Database Create Index side panel to align with the recommended Studio form patterns. ## What is the current behavior? The side panel was using a legacy layout that did not follow the common Studio form patterns. It's also not a real form. ## What is the new behavior? The Create Index side panel in the Database section is now consistent with the Studio form patterns. It's now a real form using `react-hook-form` ## Additional context Before: image After: image ## Summary by CodeRabbit * **UI Improvements** * Reworked index-creation panel into a validated, form-driven workflow with clearer field interactions, multi-column selector, live read-only SQL preview, and updated submit/cancel behavior. * Footer actions: Cancel resets the form and closes the panel; Create triggers form submission and reflects loading state. * **Tests** * Updated end-to-end flow to click "Select a table" (replacing "Choose a table") during index creation. --------- Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com> --- .../Database/Indexes/CreateIndexSidePanel.tsx | 745 +++++++++++------- e2e/studio/features/database.spec.ts | 2 +- 2 files changed, 440 insertions(+), 307 deletions(-) diff --git a/apps/studio/components/interfaces/Database/Indexes/CreateIndexSidePanel.tsx b/apps/studio/components/interfaces/Database/Indexes/CreateIndexSidePanel.tsx index 270350ebba9..88f897611dc 100644 --- a/apps/studio/components/interfaces/Database/Indexes/CreateIndexSidePanel.tsx +++ b/apps/studio/components/interfaces/Database/Indexes/CreateIndexSidePanel.tsx @@ -1,6 +1,8 @@ +import { zodResolver } from '@hookform/resolvers/zod' import { Check, ChevronsUpDown, Loader2 } from 'lucide-react' import Link from 'next/link' import { Fragment, useEffect, useMemo, useState } from 'react' +import { useForm, useWatch } from 'react-hook-form' import { toast } from 'sonner' import { Button, @@ -11,6 +13,9 @@ import { CommandInput, CommandItem, CommandList, + Form, + FormControl, + FormField, Popover, PopoverContent, PopoverTrigger, @@ -20,7 +25,13 @@ import { SelectSeparator, SelectTrigger, SelectValue, - SidePanel, + Separator, + Sheet, + SheetContent, + SheetFooter, + SheetHeader, + SheetSection, + SheetTitle, } from 'ui' import { Admonition } from 'ui-patterns' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' @@ -32,6 +43,7 @@ import { MultiSelectorTrigger, } from 'ui-patterns/multi-select' import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader' +import * as z from 'zod' import { INDEX_TYPES } from './Indexes.constants' import CodeEditor from '@/components/ui/CodeEditor/CodeEditor' @@ -48,14 +60,39 @@ interface CreateIndexSidePanelProps { onClose: () => void } +const formSchema = z.object({ + schema: z.string().min(1, 'Please provide a name for your schema'), + table: z.string().min(1, 'Please provide a name for your table'), + columns: z + .array(z.string()) + .min(1, 'Please select at least one column') + .max(32, 'You can select up to 32 columns'), + type: z.string().min(1, 'Please select an index type'), +}) + +type FormSchema = z.infer + export const CreateIndexSidePanel = ({ visible, onClose }: CreateIndexSidePanelProps) => { const { data: project } = useSelectedProjectQuery() const isOrioleDb = useIsOrioleDb() - const [selectedSchema, setSelectedSchema] = useState('public') - const [selectedEntity, setSelectedEntity] = useState(undefined) - const [selectedColumns, setSelectedColumns] = useState([]) - const [selectedIndexType, setSelectedIndexType] = useState(INDEX_TYPES[0].value) + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: { + schema: 'public', + table: '', + columns: [], + type: INDEX_TYPES[0].value, + }, + }) + + const formId = 'schema-form' + + const selectedSchema = useWatch({ name: 'schema', control: form.control }) + const selectedEntity = useWatch({ name: 'table', control: form.control }) + const selectedColumns = useWatch({ name: 'columns', control: form.control }) ?? [] + const selectedIndexType = useWatch({ name: 'type', control: form.control }) + const [schemaDropdownOpen, setSchemaDropdownOpen] = useState(false) const [tableDropdownOpen, setTableDropdownOpen] = useState(false) const [schemaSearchTerm, setSchemaSearchTerm] = useState('') @@ -98,13 +135,6 @@ export const CreateIndexSidePanel = ({ visible, onClose }: CreateIndexSidePanelP setSearchTerm(value) } - function handleSchemaSelect(schema: string) { - setSelectedSchema(schema) - setSearchTerm('') - setSchemaSearchTerm('') - setSchemaDropdownOpen(false) - } - const columns = tableColumns?.[0]?.columns ?? [] const columnOptions = columns .filter((column): column is NonNullable => column !== null) @@ -121,44 +151,14 @@ CREATE INDEX ON "${selectedSchema}"."${selectedEntity}" USING ${selectedIndexTyp .join(', ')}); `.trim() - const onSaveIndex = () => { - if (!project) return console.error('Project is required') - if (!selectedEntity) return console.error('Entity is required') - - createIndex({ - projectRef: project.ref, - connectionString: project.connectionString, - payload: { - schema: selectedSchema, - entity: selectedEntity, - type: selectedIndexType, - columns: selectedColumns, - }, - }) - } - + const { reset } = form useEffect(() => { if (visible) { - setSelectedSchema('public') - setSelectedEntity('') - setSelectedColumns([]) - setSelectedIndexType(INDEX_TYPES[0].value) + reset() setSchemaSearchTerm('') setSearchTerm('') } - }, [visible]) - - useEffect(() => { - setSelectedEntity('') - setSelectedColumns([]) - setSelectedIndexType(INDEX_TYPES[0].value) - setSearchTerm('') - }, [selectedSchema]) - - useEffect(() => { - setSelectedColumns([]) - setSelectedIndexType(INDEX_TYPES[0].value) - }, [selectedEntity]) + }, [visible, reset]) useEffect(() => { if (!schemaDropdownOpen) setSchemaSearchTerm('') @@ -166,272 +166,405 @@ CREATE INDEX ON "${selectedSchema}"."${selectedEntity}" USING ${selectedIndexTyp const isSelectEntityDisabled = entityTypes.length === 0 && searchTerm.trim().length === 0 + function onSubmit(values: z.infer) { + if (!project) return console.error('Project is required') + if (!selectedEntity) return console.error('Entity is required') + + createIndex({ + projectRef: project.ref, + connectionString: project.connectionString, + payload: { + schema: values.schema, + entity: values.table, + type: values.type, + columns: values.columns, + }, + }) + } + return ( - onSaveIndex()} - loading={isExecuting} - confirmText="Create index" - > -
- - - - - - - - - - 7 && 'max-h-[210px]! overflow-y-auto')} - onWheel={(event) => event.stopPropagation()} - > - No schemas found - - {(schemas ?? []).map((schema) => ( - { - handleSchemaSelect(schema.name) - }} - onClick={() => { - handleSchemaSelect(schema.name) - }} - > - {schema.name} - {selectedSchema === schema.name && ( - - )} - - ))} - - - - - - - - onClose()}> + + + Create new index + +
+ - - - - - - {/* [Terry] shouldFilter context: - https://github.com/pacocoursey/cmdk/issues/267#issuecomment-2252717107 */} - - - 7 && 'max-h-[210px]! overflow-y-auto')} - onWheel={(event) => event.stopPropagation()} + + ( + + + + + + + + + + 7 && 'max-h-[210px]! overflow-y-auto' + )} + onWheel={(event) => event.stopPropagation()} + > + No schemas found + + {(schemas ?? []).map((schema) => ( + { + field.onChange(schema.name) + form.setValue('table', '') + form.setValue('columns', []) + form.setValue('type', INDEX_TYPES[0].value) + setSearchTerm('') + }} + > + + {schema.name} + + ))} + + + + + + + + )} + /> + + + + + + ( + - - {isLoadingEntities ? ( -
- - Loading... + + + + + + + {/* [Terry] shouldFilter context: + https://github.com/pacocoursey/cmdk/issues/267#issuecomment-2252717107 */} + + + 7 && 'max-h-[210px]! overflow-y-auto' + )} + onWheel={(event) => event.stopPropagation()} + > + + {isLoadingEntities ? ( +
+ + Loading... +
+ ) : ( + 'No tables found' + )} +
+ + {entityTypes.map((entity) => ( + { + field.onChange(entity.name) + setTableDropdownOpen(false) + form.setValue('columns', []) + form.setValue('type', INDEX_TYPES[0].value) + }} + > + + {entity.name} + + ))} + +
+
+
+
+
+ + )} + /> + + + + + {selectedEntity && ( + + ( + + {isLoadingTableColumns && } + {isSuccessTableColumns && ( +
+ + + + + {columnOptions.map((option) => ( + + {option.name} + + ))} + + +
- ) : ( - 'No tables found' )} - - - {entityTypes.map((entity) => ( - { - setSelectedEntity(entity.name) - setTableDropdownOpen(false) - }} - onClick={() => { - setSelectedEntity(entity.name) - setTableDropdownOpen(false) - }} - > - {entity.name} - {selectedEntity === entity.name && ( - - )} - - ))} - - - - - -
- - {selectedEntity && ( - - {isLoadingTableColumns && } - {isSuccessTableColumns && ( - - - - - {columnOptions.map((option) => ( - - {option.name} - - ))} - - - - )} - - )} - - - {selectedColumns.length > 0 && ( - <> - - - - - - {isOrioleDb && ( - - {/* [Joshen Oriole] Hook up proper docs URL */} - - - )} - - - -
-

Preview of SQL statement

- -
-
-
-
- + )} /> -
-
- - )} -
- +
+ )} + + + + {selectedColumns.length > 0 && ( + <> + + ( + <> + + + + + + + {isOrioleDb && ( + + {/* [Joshen Oriole] Hook up proper docs URL */} + + + )} + + )} + /> + + + + +
+

Preview of SQL statement

+ +
+
+
+
+ +
+
+ + )} + + + + + + +
+ ) } diff --git a/e2e/studio/features/database.spec.ts b/e2e/studio/features/database.spec.ts index e0e756fd384..8a851496448 100644 --- a/e2e/studio/features/database.spec.ts +++ b/e2e/studio/features/database.spec.ts @@ -730,7 +730,7 @@ test.describe('Database', () => { // create new index await page.getByRole('button', { name: 'Create index' }).click() - await page.getByRole('button', { name: 'Choose a table' }).click() + await page.getByRole('button', { name: 'Select a table' }).click() const columnsWait = waitForApiResponse( page, From f5c49e89c557e45cc8e7e8f8962250310bc93a8a Mon Sep 17 00:00:00 2001 From: "Andrey A." <56412611+aantti@users.noreply.github.com> Date: Mon, 8 Jun 2026 12:23:36 +0200 Subject: [PATCH 013/134] chore(self-hosted): expand smoke tests (#46722) --- .github/workflows/self-host-tests-smoke.yml | 63 +++++++++++++++++++-- docker/CONFIG.md | 2 +- docker/tests/test-container-logs.sh | 18 ++++-- 3 files changed, 72 insertions(+), 11 deletions(-) diff --git a/.github/workflows/self-host-tests-smoke.yml b/.github/workflows/self-host-tests-smoke.yml index f4240f70fbb..d09f06b80fa 100644 --- a/.github/workflows/self-host-tests-smoke.yml +++ b/.github/workflows/self-host-tests-smoke.yml @@ -17,19 +17,74 @@ permissions: jobs: build: runs-on: blacksmith-4vcpu-ubuntu-2404 + strategy: + fail-fast: false + matrix: + config: [default, logs, envoy, rustfs, envoy-rustfs] steps: - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - uses: actions/checkout@v4 with: persist-credentials: false sparse-checkout: | docker/ - - name: Run docker-compose up + + - uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Generate keys + shell: bash + run: | + set -euo pipefail + cd docker + cp .env.example .env + sh utils/generate-keys.sh --update-env + sh utils/add-new-auth-keys.sh --update-env + + - name: Start self-hosted Supabase shell: bash # Ensure all services can be started and healthy with default config run: | set -euo pipefail cd docker - cp .env.example .env yq -i '.services.supavisor.environment.RLIMIT_NOFILE=1024' docker-compose.yml - docker compose up --quiet-pull --wait --wait-timeout 180 + if [ "${{ matrix.config }}" = "logs" ]; then + docker compose -f docker-compose.yml -f docker-compose.logs.yml up --quiet-pull --wait --wait-timeout 180 + elif [ "${{ matrix.config }}" = "envoy" ]; then + docker compose -f docker-compose.yml -f docker-compose.envoy.yml up --quiet-pull --wait --wait-timeout 180 + elif [ "${{ matrix.config }}" = "rustfs" ]; then + docker compose -f docker-compose.yml -f docker-compose.rustfs.yml up --quiet-pull --wait --wait-timeout 180 + elif [ "${{ matrix.config }}" = "envoy-rustfs" ]; then + docker compose -f docker-compose.yml -f docker-compose.envoy.yml -f docker-compose.rustfs.yml up --quiet-pull --wait --wait-timeout 180 + else + docker compose up --quiet-pull --wait --wait-timeout 180 + fi + + - name: Run container log tests + shell: bash + run: | + set -euo pipefail + cd docker + sh tests/test-container-logs.sh + + - name: Run smoke tests + shell: bash + run: | + set -euo pipefail + cd docker + sh tests/test-self-hosted.sh + + - name: Run API keys and asymmetric auth tests + shell: bash + run: | + set -euo pipefail + cd docker + sh tests/test-auth-keys.sh + + - name: Run S3 protocol tests + shell: bash + run: | + set -euo pipefail + cd docker + sh tests/test-s3.sh diff --git a/docker/CONFIG.md b/docker/CONFIG.md index d139fc984e6..f4bd19eebe1 100644 --- a/docker/CONFIG.md +++ b/docker/CONFIG.md @@ -138,7 +138,7 @@ Self-hosted Studio reads `ENABLED_FEATURES_*` env vars at container start time t | Variable | Type | Set by | Description | Notes | |---|---|---|---|---| | `ENABLED_FEATURES_*` | boolean | | Per-flag runtime override. Set to `true` or `false` (case-insensitive); other values are logged and ignored. | One env var per flag. Full key list: `packages/common/enabled-features/enabled-features.json`. No-op when `NEXT_PUBLIC_IS_PLATFORM=true`. | -| `ENABLED_FEATURES_LOGS_ALL` | boolean | | Disable the entire Logs section of the dashboard. Maps to the `logs:all` feature flag. | Documented explicitly as the runtime replacement for the legacy build-time `NEXT_PUBLIC_ENABLE_LOGS`. | +| `ENABLED_FEATURES_LOGS_ALL` | boolean | Self-hosted | Disable the entire Logs section of the dashboard. Maps to the `logs:all` feature flag. | Documented explicitly as the runtime replacement for the legacy build-time `NEXT_PUBLIC_ENABLE_LOGS`. | ### AI features diff --git a/docker/tests/test-container-logs.sh b/docker/tests/test-container-logs.sh index 75ecd100c2a..be5068bd170 100644 --- a/docker/tests/test-container-logs.sh +++ b/docker/tests/test-container-logs.sh @@ -62,31 +62,37 @@ get_container_id() { printf '%s' "$1" } -# Check that a service's logs contain all expected patterns +# Check that a service's logs contain all expected patterns. +# Logs are written to a temp file so that grep -q exits cleanly. check_logs() { service="$1" shift - logs=$(docker compose logs "$service" 2>/dev/null || true) - if [ -z "$logs" ]; then + logfile=$(mktemp) + + docker compose logs "$service" > "$logfile" 2>/dev/null || true + if [ ! -s "$logfile" ]; then container_id=$(get_container_id "$service") if [ -n "$container_id" ]; then - logs=$(docker logs "$container_id" 2>&1 || true) + docker logs "$container_id" > "$logfile" 2>&1 || true fi fi - if [ -z "$logs" ]; then + if [ ! -s "$logfile" ]; then + rm -f "$logfile" fail_msg "$service (no logs found)" return fi for pattern in "$@"; do - if ! echo "$logs" | grep -q -i -E "$pattern"; then + if ! grep -q -i -E "$pattern" "$logfile"; then + rm -f "$logfile" fail_msg "$service (missing: $pattern)" return fi done + rm -f "$logfile" pass_msg "$service" } From 7693d6ceda72261a35ed41383b03a34666b4d280 Mon Sep 17 00:00:00 2001 From: Taryn King <49492414+tk1ng@users.noreply.github.com> Date: Mon, 8 Jun 2026 05:37:10 -0500 Subject: [PATCH 014/134] docs(auth hooks): clarify hook name must match available hooks (#40220) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Docs update ## What is the current behavior? Auth hooks documentation doesn't explicitly state that the hook name configured in `config.toml` must correspond to available hooks to prevent errors, which has caused confusion for some users. ## What is the new behavior? Doc includes mention that hook name must correspond to available hooks. ## Additional context ## Summary by CodeRabbit * **Documentation** * Added clarification note regarding authentication hook configuration requirements, specifying that hook names in configuration files must correspond to available hook types. --------- Co-authored-by: Chris Chinchilla --- apps/docs/content/guides/auth/auth-hooks.mdx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/docs/content/guides/auth/auth-hooks.mdx b/apps/docs/content/guides/auth/auth-hooks.mdx index bc0a4d34ede..b1259bc1d5a 100644 --- a/apps/docs/content/guides/auth/auth-hooks.mdx +++ b/apps/docs/content/guides/auth/auth-hooks.mdx @@ -148,6 +148,12 @@ Let us develop a Hook locally and then deploy it to the cloud. As a recap, here Edit `config.toml` to set up the Auth Hook locally. + + + The hook name used in the `config.toml` must correspond to one of the available Hooks listed above. For example, the Send SMS hook would be configured as: `[auth.hook.send_sms]` + + + Date: Mon, 8 Jun 2026 07:38:03 -0300 Subject: [PATCH 015/134] fix(docker): add healthcheck to edge functions container (#46655) --- docker/docker-compose.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 3e522ccd67d..3f5ce3f604a 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -437,6 +437,11 @@ services: depends_on: kong: condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "timeout 1 bash -c ' Date: Mon, 8 Jun 2026 13:11:32 +0200 Subject: [PATCH 016/134] fix(reports): guard against malformed URI in route renderer (#46729) ## Problem The PostgREST observability page crashes for some projects with `URIError: URI malformed`. The route renderer calls `decodeURIComponent` directly on the request query string, which is user-controlled. A malformed percent-sequence (for example a literal `%` in `?discount=100%`) makes `decodeURIComponent` throw during render, taking down the whole page via the global error boundary. Tracked in Sentry issue 7536581822. ## Fix Add a `safeDecodeURIComponent` helper that wraps `decodeURIComponent` in a try/catch and falls back to the raw string on failure. Use it in the route renderer. The sibling `queryParamsToObject` call is unaffected since `URLSearchParams` already tolerates malformed escapes. ## How to test - Open a project's PostgREST observability report (`/project/[ref]/observability/postgrest`). - Ensure a request with a malformed query string (e.g. a path containing a bare `%`) appears in the data. - Expected result: the row renders with the raw search string instead of crashing the page. - Unit tests for `safeDecodeURIComponent` cover valid decode, malformed input, and empty string. --------- Co-authored-by: Claude Opus 4.8 --- .../interfaces/Reports/Reports.utils.test.ts | 16 +++++++++++++++- .../interfaces/Reports/Reports.utils.tsx | 15 +++++++++++++++ .../Reports/renderers/ApiRenderers.tsx | 4 ++-- .../Reports/renderers/StorageRenderers.tsx | 3 ++- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/apps/studio/components/interfaces/Reports/Reports.utils.test.ts b/apps/studio/components/interfaces/Reports/Reports.utils.test.ts index 20fe9aba5b0..0164000cc7e 100644 --- a/apps/studio/components/interfaces/Reports/Reports.utils.test.ts +++ b/apps/studio/components/interfaces/Reports/Reports.utils.test.ts @@ -2,10 +2,24 @@ import dayjs from 'dayjs' import utc from 'dayjs/plugin/utc' import { describe, expect, it } from 'vitest' -import { formatTimestamp } from './Reports.utils' +import { formatTimestamp, safeDecodeURIComponent } from './Reports.utils' dayjs.extend(utc) +describe('safeDecodeURIComponent', () => { + it('decodes a valid percent-encoded string', () => { + expect(safeDecodeURIComponent('a%20b')).toBe('a b') + }) + + it('returns the original string when percent-encoding is malformed', () => { + expect(safeDecodeURIComponent('?discount=100%')).toBe('?discount=100%') + }) + + it('handles an empty string', () => { + expect(safeDecodeURIComponent('')).toBe('') + }) +}) + describe('formatTimestamp', () => { it('formats milliseconds timestamp correctly', () => { const timestamp = 1640995200000 // 2022-01-01 00:00:00 UTC in milliseconds diff --git a/apps/studio/components/interfaces/Reports/Reports.utils.tsx b/apps/studio/components/interfaces/Reports/Reports.utils.tsx index 46ab235753e..f27ee797ef5 100644 --- a/apps/studio/components/interfaces/Reports/Reports.utils.tsx +++ b/apps/studio/components/interfaces/Reports/Reports.utils.tsx @@ -23,6 +23,21 @@ export const queryParamsToObject = (params: string) => { return Object.fromEntries(new URLSearchParams(params)) } +/** + * Decodes a URI component, returning the original string if it is malformed. + * + * `decodeURIComponent` throws a `URIError` on invalid percent-encoding (e.g. a + * literal `%` such as `?discount=100%`). Request paths are user-controlled, so + * decoding inline during render can crash the page. + */ +export const safeDecodeURIComponent = (value: string) => { + try { + return decodeURIComponent(value) + } catch { + return value + } +} + export type PresetHookResult = LogsQueryHook | DbQueryHook type PresetHooks = Record PresetHookResult> /** diff --git a/apps/studio/components/interfaces/Reports/renderers/ApiRenderers.tsx b/apps/studio/components/interfaces/Reports/renderers/ApiRenderers.tsx index 1605756437f..f5fdaf149e4 100644 --- a/apps/studio/components/interfaces/Reports/renderers/ApiRenderers.tsx +++ b/apps/studio/components/interfaces/Reports/renderers/ApiRenderers.tsx @@ -16,7 +16,7 @@ import { } from 'ui' import * as z from 'zod' -import { queryParamsToObject } from '../Reports.utils' +import { queryParamsToObject, safeDecodeURIComponent } from '../Reports.utils' import { ReportWidgetProps, ReportWidgetRendererProps } from '../ReportWidget' import { COUNTRY_LAT_LON } from '@/components/interfaces/ProjectCreation/ProjectCreation.constants' import { @@ -372,7 +372,7 @@ const RouteTdContent = (datum: RouteTdContentProps) => (
diff --git a/apps/studio/components/interfaces/Reports/renderers/StorageRenderers.tsx b/apps/studio/components/interfaces/Reports/renderers/StorageRenderers.tsx index db27d752f99..3659b64a2a4 100644 --- a/apps/studio/components/interfaces/Reports/renderers/StorageRenderers.tsx +++ b/apps/studio/components/interfaces/Reports/renderers/StorageRenderers.tsx @@ -1,5 +1,6 @@ import { Fragment } from 'react' +import { safeDecodeURIComponent } from '../Reports.utils' import { ReportWidgetProps, ReportWidgetRendererProps } from '../ReportWidget' import { TextFormatter } from '@/components/interfaces/Settings/Logs/LogsFormatters' import Table from '@/components/to-be-cleaned/Table' @@ -70,7 +71,7 @@ export const TopCacheMissesRenderer = ( From 567162c38f776102188c946b8781abb7b87f85ef Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Mon, 8 Jun 2026 13:51:40 +0200 Subject: [PATCH 017/134] docs: Move JS debug page for data API (#46721) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## Summary by CodeRabbit * **Chores** * Reorganized REST API documentation navigation to consolidate debugging resources under a dedicated subsection for improved discoverability. --- .../NavigationMenu/NavigationMenu.constants.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts index d2fdb96c6be..e6a75d5cc5c 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts @@ -1575,10 +1575,6 @@ export const api: NavMenuConstant = { { name: 'Generating TypeScript Types', url: '/guides/api/rest/generating-types' }, { name: 'Generating Python Types', url: '/guides/api/rest/generating-python-types' }, { name: 'Error Codes', url: '/guides/api/rest/postgrest-error-codes' }, - { - name: 'Handling Errors in supabase-js', - url: '/guides/api/handling-errors-in-supabase-js', - }, ], }, { @@ -1619,6 +1615,16 @@ export const api: NavMenuConstant = { }, ], }, + { + name: 'Debugging', + url: undefined, + items: [ + { + name: 'Handling Errors in supabase-js', + url: '/guides/api/handling-errors-in-supabase-js', + }, + ], + }, ], } From 4b2e9a206cef7a9d140afe621063fb25a21bef07 Mon Sep 17 00:00:00 2001 From: Katerina Skroumpelou Date: Mon, 8 Jun 2026 15:33:20 +0300 Subject: [PATCH 018/134] fix(docs): scope js-libs-update vitest run and make tests self-contained (#46737) The `Update JS Client Libraries Docs` workflow's "Refresh reference-content snapshot" step fails because `npx vitest run --update scripts/build-reference-content.test.ts` is treated as a filter, not a restriction, under Vitest 4, so all docs tests run. `CodeSample.test.ts` then fails with ENOENT on `apps/docs/examples/_internal/fixtures/*` because the workflow bypasses the `pretest` npm hook that runs `codegen:examples`. This is a regression of #44943 (commit 28ef62cf31), reintroduced by #46163 when the snapshot step was renamed and rewritten back to the file-path form. Fixes: - Workflow: use `--dir scripts` so only the snapshot test runs. - Tests: add a vitest globalSetup that mirrors `codegen:examples`, so `npx vitest`, `pnpm test:local`, and IDE single-test runs no longer depend on the `pretest` lifecycle hook being triggered first. ## Summary by CodeRabbit * **Chores** * Updated test infrastructure configuration and initialization process for improved test suite management. * Refined test execution workflow to efficiently manage test discovery and execution across project directories. --- .github/workflows/docs-js-libs-update.yml | 4 ++-- apps/docs/vitest.config.ts | 2 +- apps/docs/vitest.globalSetup.ts | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 apps/docs/vitest.globalSetup.ts diff --git a/.github/workflows/docs-js-libs-update.yml b/.github/workflows/docs-js-libs-update.yml index dc025041509..68eeb3434bb 100644 --- a/.github/workflows/docs-js-libs-update.yml +++ b/.github/workflows/docs-js-libs-update.yml @@ -54,7 +54,8 @@ jobs: - name: Refresh reference-content snapshot working-directory: apps/docs - run: npx vitest run --update scripts/build-reference-content.test.ts + # Using --dir (not a file path) so Vitest 4 doesn't run unrelated tests. + run: npx vitest run --update --dir scripts - name: Generate token id: app-token @@ -65,7 +66,6 @@ jobs: permission-contents: write permission-pull-requests: write - - name: Create pull request uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 with: diff --git a/apps/docs/vitest.config.ts b/apps/docs/vitest.config.ts index 25dac66db18..30c7c2703b9 100644 --- a/apps/docs/vitest.config.ts +++ b/apps/docs/vitest.config.ts @@ -1,12 +1,12 @@ import tsconfigPaths from 'vite-tsconfig-paths' import { defineConfig } from 'vitest/config' -// eslint-disable-next-line no-restricted-exports export default defineConfig({ test: { // Exclude examples from test discovery (does not affect tsconfig scanning) exclude: ['examples/**/*', '**/node_modules/**'], setupFiles: ['vitest.setup.ts'], + globalSetup: ['vitest.globalSetup.ts'], }, // Restrict tsconfig-paths to only use this app's tsconfig plugins: [ diff --git a/apps/docs/vitest.globalSetup.ts b/apps/docs/vitest.globalSetup.ts new file mode 100644 index 00000000000..905ad823385 --- /dev/null +++ b/apps/docs/vitest.globalSetup.ts @@ -0,0 +1,16 @@ +import { cpSync, existsSync } from 'node:fs' +import { join } from 'node:path' + +// Mirrors `pnpm run codegen:examples` so the test suite is self-contained. +// CodeSample.test.ts reads fixtures from apps/docs/examples/_internal/fixtures/, +// which are sourced from the repo-root examples/ directory. Without this, +// `npx vitest`, `pnpm test:local`, or IDE single-test runs all fail with ENOENT +// because they bypass the `pretest` npm lifecycle hook. +export default function setup() { + const source = join(import.meta.dirname, '..', '..', 'examples') + const dest = join(import.meta.dirname, 'examples') + if (!existsSync(source)) { + throw new Error(`Expected repo-root examples directory at ${source}`) + } + cpSync(source, dest, { recursive: true }) +} From 30d32dd22cf557977295a0369d3492fb658c696c Mon Sep 17 00:00:00 2001 From: "Andrey A." <56412611+aantti@users.noreply.github.com> Date: Mon, 8 Jun 2026 14:49:16 +0200 Subject: [PATCH 019/134] chore(self-hosted): add test for tus (#46731) --- docker/tests/test-self-hosted.sh | 120 +++++++++++++++++++++++++++++-- 1 file changed, 115 insertions(+), 5 deletions(-) diff --git a/docker/tests/test-self-hosted.sh b/docker/tests/test-self-hosted.sh index 87e3c5b64ca..f1dc0f7f811 100644 --- a/docker/tests/test-self-hosted.sh +++ b/docker/tests/test-self-hosted.sh @@ -10,6 +10,7 @@ # - Running self-hosted Supabase instance # - .env file with keys configured # - jq (for JSON parsing) +# - sha256sum or shasum (for file integrity checks) # set -e @@ -29,6 +30,16 @@ if ! command -v jq >/dev/null 2>&1; then exit 1 fi +# Portable file hash: prefers sha256sum (Linux), falls back to shasum (macOS) +if command -v sha256sum >/dev/null 2>&1; then + file_hash() { sha256sum "$1" | awk '{print $1}'; } +elif command -v shasum >/dev/null 2>&1; then + file_hash() { shasum -a 256 "$1" | awk '{print $1}'; } +else + echo "Error: sha256sum or shasum not found." + exit 1 +fi + # Read keys from .env ANON_KEY=$(grep '^ANON_KEY=' .env | cut -d= -f2-) SERVICE_ROLE_KEY=$(grep '^SERVICE_ROLE_KEY=' .env | cut -d= -f2-) @@ -235,12 +246,16 @@ if [ "$create_bucket_status" = "200" ]; then --data-binary "@$tmpfile") check "Upload 7MB file" "200" "$upload_status" - # Download file and verify size - download_size=$(curl -s \ - "$BASE_URL/storage/v1/object/public/$bucket_name/test-large-file.bin" | wc -c | tr -d ' ') + # Download file and verify integrity + download_tmp=$(mktemp); cleanup_files="$cleanup_files $download_tmp" + curl -s "$BASE_URL/storage/v1/object/public/$bucket_name/test-large-file.bin" -o "$download_tmp" original_size=$(wc -c < "$tmpfile" | tr -d ' ') - check "Download file (size matches)" "true" \ - "$([ "$download_size" = "$original_size" ] && echo true || echo false)" + download_size=$(wc -c < "$download_tmp" | tr -d ' ') + check "Download file (size matches)" "$original_size" "$download_size" + original_hash=$(file_hash "$tmpfile") + download_hash=$(file_hash "$download_tmp") + check "Download file (hash matches)" "$original_hash" "$download_hash" + rm -f "$download_tmp" rm -f "$tmpfile" @@ -293,6 +308,101 @@ if [ "$create_bucket_status" = "200" ]; then check "Delete bucket" "200" "$delete_bucket_status" fi +# --------------------------------------------- +# 6b. Storage: TUS resumable upload +# --------------------------------------------- + +echo "" +echo "--- Storage: TUS resumable upload ---" + +tus_bucket="smoke-tus-$$" + +tus_bucket_status=$(http_status "$BASE_URL/storage/v1/bucket" \ + -X POST \ + -H "apikey: $SERVICE_ROLE_KEY" \ + -H "Authorization: Bearer $SERVICE_ROLE_KEY" \ + -H "Content-Type: application/json" \ + -d "{\"id\":\"$tus_bucket\",\"name\":\"$tus_bucket\",\"public\":true}") +check "TUS: create bucket" "200" "$tus_bucket_status" + +if [ "$tus_bucket_status" = "200" ]; then + # Generate a ~7MB file (above Studio's 6MB TUS threshold) + tusfile=$(mktemp); cleanup_files="$cleanup_files $tusfile" + dd if=/dev/urandom of="$tusfile" bs=1048576 count=7 2>/dev/null + tus_file_size=$(wc -c < "$tusfile" | tr -d ' ') + tus_chunk_size=$((4 * 1048576)) # 4MB first chunk + + # Encode TUS metadata values as base64 + tus_bucket_b64=$(printf '%s' "$tus_bucket" | base64) + tus_object_b64=$(printf '%s' "tus-test-file.bin" | base64) + tus_mime_b64=$(printf '%s' "application/octet-stream" | base64) + + # 1. Create resumable upload + tus_create_resp=$(curl -s -i -X POST \ + "$BASE_URL/storage/v1/upload/resumable" \ + -H "apikey: $SERVICE_ROLE_KEY" \ + -H "Authorization: Bearer $SERVICE_ROLE_KEY" \ + -H "Tus-Resumable: 1.0.0" \ + -H "Upload-Length: $tus_file_size" \ + -H "Upload-Metadata: bucketName $tus_bucket_b64,objectName $tus_object_b64,contentType $tus_mime_b64" \ + -H "x-upsert: true") + tus_create_status=$(echo "$tus_create_resp" | grep -m1 '^HTTP/' | grep -o '[0-9][0-9][0-9]') + # Supabase Storage always returns an absolute Location URL (see generateUrl in storage/src/http/routes/tus/lifecycle.ts) + tus_location=$(echo "$tus_create_resp" | grep -i '^location:' | tr -d '\r' | sed 's/^[Ll]ocation: *//') + check "TUS: create resumable upload" "201" "$tus_create_status" + + if [ -n "$tus_location" ]; then + # 2. Upload first chunk (0 to 4MB) + tus_chunk1_status=$(dd if="$tusfile" bs=1048576 count=4 2>/dev/null | \ + curl -s -o /dev/null -w "%{http_code}" -X PATCH \ + "$tus_location" \ + -H "apikey: $SERVICE_ROLE_KEY" \ + -H "Authorization: Bearer $SERVICE_ROLE_KEY" \ + -H "Tus-Resumable: 1.0.0" \ + -H "Upload-Offset: 0" \ + -H "Content-Type: application/offset+octet-stream" \ + --data-binary @-) + check "TUS: upload chunk 1 (4MB)" "204" "$tus_chunk1_status" + + # 3. Upload second chunk (4MB to end) + tus_remaining=$((tus_file_size - tus_chunk_size)) + tus_chunk2_status=$(dd if="$tusfile" bs=1048576 skip=4 count=3 2>/dev/null | \ + curl -s -o /dev/null -w "%{http_code}" -X PATCH \ + "$tus_location" \ + -H "apikey: $SERVICE_ROLE_KEY" \ + -H "Authorization: Bearer $SERVICE_ROLE_KEY" \ + -H "Tus-Resumable: 1.0.0" \ + -H "Upload-Offset: $tus_chunk_size" \ + -H "Content-Type: application/offset+octet-stream" \ + --data-binary @-) + check "TUS: upload chunk 2 (remaining)" "204" "$tus_chunk2_status" + + # 4. Verify download matches original (hash check proves correct chunk reassembly) + tus_download_tmp=$(mktemp); cleanup_files="$cleanup_files $tus_download_tmp" + curl -s "$BASE_URL/storage/v1/object/public/$tus_bucket/tus-test-file.bin" -o "$tus_download_tmp" + tus_download_size=$(wc -c < "$tus_download_tmp" | tr -d ' ') + check "TUS: download size matches" "$tus_file_size" "$tus_download_size" + tus_original_hash=$(file_hash "$tusfile") + tus_download_hash=$(file_hash "$tus_download_tmp") + check "TUS: download hash matches" "$tus_original_hash" "$tus_download_hash" + rm -f "$tus_download_tmp" + fi + + rm -f "$tusfile" + + # Cleanup: delete file and bucket + http_status "$BASE_URL/storage/v1/object/$tus_bucket/tus-test-file.bin" \ + -X DELETE \ + -H "apikey: $SERVICE_ROLE_KEY" \ + -H "Authorization: Bearer $SERVICE_ROLE_KEY" >/dev/null 2>&1 + + tus_delete_bucket=$(http_status "$BASE_URL/storage/v1/bucket/$tus_bucket" \ + -X DELETE \ + -H "apikey: $SERVICE_ROLE_KEY" \ + -H "Authorization: Bearer $SERVICE_ROLE_KEY") + check "TUS: delete bucket" "200" "$tus_delete_bucket" +fi + # --------------------------------------------- # 7. Edge Functions # --------------------------------------------- From c75250ba9e3a02a34b72960dd2c893cfc5467464 Mon Sep 17 00:00:00 2001 From: "supabase-supabase-autofixer[bot]" <248690971+supabase-supabase-autofixer[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 12:49:48 +0000 Subject: [PATCH 020/134] [bot] Sync from supabase/troubleshooting (#46725) This PR syncs the latest troubleshooting guides from the supabase/troubleshooting repository. --------- Co-authored-by: github-docs-bot Co-authored-by: Chris Chinchilla --- ...-in-vercel-serverless-functions-775f92.mdx | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 apps/docs/content/troubleshooting/troubleshooting-connect_timeout-or-hanging-queries-in-vercel-serverless-functions-775f92.mdx diff --git a/apps/docs/content/troubleshooting/troubleshooting-connect_timeout-or-hanging-queries-in-vercel-serverless-functions-775f92.mdx b/apps/docs/content/troubleshooting/troubleshooting-connect_timeout-or-hanging-queries-in-vercel-serverless-functions-775f92.mdx new file mode 100644 index 00000000000..3477600da21 --- /dev/null +++ b/apps/docs/content/troubleshooting/troubleshooting-connect_timeout-or-hanging-queries-in-vercel-serverless-functions-775f92.mdx @@ -0,0 +1,21 @@ +--- +title = "Troubleshooting 'CONNECT_TIMEOUT' or hanging queries in Serverless Functions" +date_created = "2026-06-08T10:04:54+00:00" +topics = [ "database", "functions", "supavisor" ] +keywords = [] +[[errors]] +code = "CONNECT_TIMEOUT" +message = "connection timeout errors" +--- + +Intermittent `CONNECT_TIMEOUT` errors or queries that hang until reaching the execution limit may occur when using persistent clients, such as `postgres-js`, within Serverless Functions. + +**Why Does This Happen?** +Serverless environments may freeze the function between requests. This causes TCP sockets to go stale because the connection pooler or NAT may drop inactive connections while the client-side `keepalive` timers are paused. Upon resuming the function, the client attempts to reuse the dead socket, leading to a hang. + +**How to Resolve This:** + +- **Use the Data API:** Migrate read-heavy workloads to the Supabase Data API (PostgREST). This utilizes stateless HTTP requests and avoids persistent TCP socket issues. +- **Liveness Preflight:** For transactional paths using `postgres-js`, implement a preflight check by racing a `SELECT 1` query against a short timeout (e.g., a few seconds) before executing the primary query. If the preflight times out, recycle the database client. +- **Migrate to Vercel Fluid Compute:** Use Vercel's Fluid Compute with `attachDatabasePool`. This environment supports the `waitUntil` hook, which allows the runtime to close idle connections properly before the instance suspends. +- **Application Retries:** Implement application-level retry logic specifically for connection timeout errors to force a new connection attempt. From 895726505f1cb7393760482ce5e243463550a01a Mon Sep 17 00:00:00 2001 From: Jordi Enric <37541088+jordienr@users.noreply.github.com> Date: Mon, 8 Jun 2026 15:10:03 +0200 Subject: [PATCH 021/134] feat(studio): dedicated telemetry events for org audit log drains (#46733) ## Problem The org Audit Log Drains page fires the same `log_drain_save_button_clicked` and `log_drain_removed` telemetry events as the project Log Drains page, even though they are distinct features (project product logs vs. the org audit log). Org-scoped events should have their own names and drop the project group. ## Fix Add dedicated org-scoped events and use them in the org container: - `audit_log_drain_save_button_clicked` - `audit_log_drain_removed` Both declare `groups: Omit` (no project group), matching the convention used by other org-scoped events (e.g. the documents page events). The project Log Drains page keeps the original `log_drain_*` events unchanged. ## How to test - Open `/org/{slug}/audit-log-drains` (with the `auditLogsLogDrain` flag enabled). - Create a drain and confirm `audit_log_drain_save_button_clicked` fires (with the destination type, org group, no project group). - Delete a drain and confirm `audit_log_drain_removed` fires. - Confirm the project Log Drains page still fires `log_drain_*` events. ## Summary by CodeRabbit * **Chores** * Updated internal telemetry tracking for audit log drain operations to improve monitoring and analytics of system behavior. Co-authored-by: Claude Opus 4.8 --- .../LogDrains/OrgAuditLogDrains.tsx | 4 +- packages/common/telemetry-constants.ts | 62 +++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/apps/studio/components/interfaces/LogDrains/OrgAuditLogDrains.tsx b/apps/studio/components/interfaces/LogDrains/OrgAuditLogDrains.tsx index ef1a849ce07..08737854684 100644 --- a/apps/studio/components/interfaces/LogDrains/OrgAuditLogDrains.tsx +++ b/apps/studio/components/interfaces/LogDrains/OrgAuditLogDrains.tsx @@ -210,7 +210,7 @@ export function OrgAuditLogDrains() { isLoading={isLoading} existingDrainNames={(logDrains ?? []).map((drain) => drain.name)} onSaveClick={(type) => { - track('log_drain_save_button_clicked', { destination: type }) + track('audit_log_drain_save_button_clicked', { destination: type }) }} onSubmit={({ name, description, type, ...values }) => { const logDrainValues = { @@ -245,7 +245,7 @@ export function OrgAuditLogDrains() { onNewDrainClick={handleNewClick} onDeleteDrain={(drain) => { deleteLogDrain({ token: drain.token, slug }) - track('log_drain_removed', { destination: drain.type }) + track('audit_log_drain_removed', { destination: drain.type }) }} onTestDrain={(drain) => testLogDrain({ token: drain.token, slug })} /> diff --git a/packages/common/telemetry-constants.ts b/packages/common/telemetry-constants.ts index c55879f79ef..a06cd36d605 100644 --- a/packages/common/telemetry-constants.ts +++ b/packages/common/telemetry-constants.ts @@ -2509,6 +2509,66 @@ export interface LogDrainRemovedEvent { groups: TelemetryGroups } +/** + * User clicked the save destination button in the add audit log drain sheet. + * + * @group Events + * @source studio + * @page /dashboard/org/{slug}/audit-log-drains (LogDrainDestinationSheetForm) + */ +export interface AuditLogDrainSaveButtonClickedEvent { + action: 'audit_log_drain_save_button_clicked' + properties: { + /** + * Type of the destination saved + */ + destination: + | 'postgres' + | 'bigquery' + | 'clickhouse' + | 'webhook' + | 'datadog' + | 'loki' + | 'sentry' + | 's3' + | 'axiom' + | 'last9' + | 'otlp' + | 'syslog' + } + groups: Omit +} + +/** + * User confirmed removal of an audit log drain destination in the delete-confirm modal. + * + * @group Events + * @source studio + * @page /dashboard/org/{slug}/audit-log-drains + */ +export interface AuditLogDrainRemovedEvent { + action: 'audit_log_drain_removed' + properties: { + /** + * Type of the destination removed + */ + destination: + | 'postgres' + | 'bigquery' + | 'clickhouse' + | 'webhook' + | 'datadog' + | 'loki' + | 'sentry' + | 's3' + | 'axiom' + | 'last9' + | 'otlp' + | 'syslog' + } + groups: Omit +} + type AdvisorCategory = 'PERFORMANCE' | 'SECURITY' type AdvisorLevel = 'ERROR' | 'WARN' | 'INFO' @@ -3425,6 +3485,8 @@ export type TelemetryEvent = | SidebarOpenedEvent | LogDrainSaveButtonClickedEvent | LogDrainRemovedEvent + | AuditLogDrainSaveButtonClickedEvent + | AuditLogDrainRemovedEvent | AdvisorDetailOpenedEvent | AdvisorAssistantButtonClickedEvent | QueryPerformanceAIExplanationButtonClickedEvent From 8531064ad76d4a5ed07a1825e7109c7ca3fcd1cd Mon Sep 17 00:00:00 2001 From: "kemal.earth" <606977+kemaldotearth@users.noreply.github.com> Date: Mon, 8 Jun 2026 14:12:47 +0100 Subject: [PATCH 022/134] chore(studio): small visual update to empty observability charts (#46728) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Subtle improvement to charts that cannot load data. Less floaty. | Before | After | |--------|--------| | Screenshot 2026-06-08 at 11 46 21 | Screenshot 2026-06-08 at 11 46
01 | ## Summary by CodeRabbit ## Release Notes **Style** - Improved visual styling for chart error and loading states. Chart placeholders now feature increased height and enhanced border presentation with dashed borders and rounded corners, providing clearer visual distinction when data is unavailable or unable to load. --- apps/studio/components/ui/Charts/ChartHandler.tsx | 2 +- apps/studio/components/ui/Charts/ComposedChartHandler.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/studio/components/ui/Charts/ChartHandler.tsx b/apps/studio/components/ui/Charts/ChartHandler.tsx index 480f2cfb39b..b1226ddb590 100644 --- a/apps/studio/components/ui/Charts/ChartHandler.tsx +++ b/apps/studio/components/ui/Charts/ChartHandler.tsx @@ -149,7 +149,7 @@ const ChartHandler = ({ if (chartData === undefined) { return ( -
+

Unable to load data for {label}

diff --git a/apps/studio/components/ui/Charts/ComposedChartHandler.tsx b/apps/studio/components/ui/Charts/ComposedChartHandler.tsx index 5c9e15e32da..387edfd5701 100644 --- a/apps/studio/components/ui/Charts/ComposedChartHandler.tsx +++ b/apps/studio/components/ui/Charts/ComposedChartHandler.tsx @@ -273,7 +273,7 @@ const ComposedChartHandler = ({ if (!combinedData) { return ( -
+

Unable to load data for {label}

From 10d0b63950a944fa1fd0363e515076fe027d5e4c Mon Sep 17 00:00:00 2001 From: "supabase-supabase-autofixer[bot]" <248690971+supabase-supabase-autofixer[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 16:22:02 +0300 Subject: [PATCH 023/134] feat: update @supabase/*-js libraries to v2.108.0 (#46740) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR updates @supabase/*-js libraries to version 2.108.0. **Source**: manual **Changes**: - Updated @supabase/supabase-js to 2.108.0 - Updated @supabase/auth-js to 2.108.0 - Updated @supabase/realtime-js to 2.108.0 - Updated @supabase/postgest-js to 2.108.0 - Refreshed pnpm-lock.yaml --- ## Release Notes ## v2.108.0 ## 2.108.0 (2026-06-08) ### 🚀 Features - **auth:** auth.resend() consistent confirmation flow ([#2144](https://github.com/supabase/supabase-js/pull/2144)) ### 🩹 Fixes - **auth:** do not console.error AuthApiError already returned through contract ([#2428](https://github.com/supabase/supabase-js/pull/2428)) - **postgrest:** pass request headers as plain object for RN/custom-fetch compatibility ([#2414](https://github.com/supabase/supabase-js/pull/2414)) ### ❤️ Thank You - Katerina Skroumpelou @mandarini - Lawrence Li @weilirs - MaitreyeeDeshmukh This PR was created automatically. Co-authored-by: supabase-workflow-trigger[bot] <266661614+supabase-workflow-trigger[bot]@users.noreply.github.com> --- pnpm-lock.yaml | 110 ++++++++++++++++++++++---------------------- pnpm-workspace.yaml | 8 ++-- 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 70cd6bae73a..e12bc9855c2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,20 +10,20 @@ catalogs: specifier: ^10.26.0 version: 10.27.0 '@supabase/auth-js': - specifier: 2.107.0 - version: 2.107.0 + specifier: 2.108.0 + version: 2.108.0 '@supabase/postgrest-js': - specifier: 2.107.0 - version: 2.107.0 + specifier: 2.108.0 + version: 2.108.0 '@supabase/realtime-js': - specifier: 2.107.0 - version: 2.107.0 + specifier: 2.108.0 + version: 2.108.0 '@supabase/ssr': specifier: 0.10.2 version: 0.10.2 '@supabase/supabase-js': - specifier: 2.107.0 - version: 2.107.0 + specifier: 2.108.0 + version: 2.108.0 '@types/node': specifier: ^22.0.0 version: 22.13.14 @@ -349,7 +349,7 @@ importers: version: 10.27.0(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.5.18(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.59.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6)(supports-color@8.1.1)(webpack@5.105.4(esbuild@0.25.2)) '@supabase/supabase-js': specifier: 'catalog:' - version: 2.107.0 + version: 2.108.0 '@tanstack/react-query': specifier: ^5.13.4 version: 5.83.0(react@19.2.6) @@ -934,7 +934,7 @@ importers: version: 9.1.0 '@supabase/auth-js': specifier: 'catalog:' - version: 2.107.0 + version: 2.108.0 '@supabase/mcp-server-supabase': specifier: ^0.7.0 version: 0.7.0(@modelcontextprotocol/sdk@1.29.0(supports-color@8.1.1)(zod@3.25.76))(zod@3.25.76) @@ -943,7 +943,7 @@ importers: version: link:../../packages/pg-meta '@supabase/realtime-js': specifier: 'catalog:' - version: 2.107.0 + version: 2.108.0 '@supabase/shared-types': specifier: 0.1.88 version: 0.1.88 @@ -952,7 +952,7 @@ importers: version: 0.1.6(encoding@0.1.13)(supports-color@8.1.1) '@supabase/supabase-js': specifier: 'catalog:' - version: 2.107.0 + version: 2.108.0 '@tanstack/react-hotkeys': specifier: ^0.9.1 version: 0.9.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -1328,7 +1328,7 @@ importers: version: 2.11.3(@types/node@22.13.14)(typescript@6.0.2) next-router-mock: specifier: ^0.9.13 - version: 0.9.13(next@16.2.6(@opentelemetry/api@1.9.0)(@playwright/test@1.59.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6) + version: 0.9.13(next@16.2.6(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.59.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6) node-mocks-http: specifier: ^1.17.2 version: 1.17.2(@types/node@22.13.14) @@ -1379,7 +1379,7 @@ importers: version: 0.1.0 '@supabase/postgrest-js': specifier: 'catalog:' - version: 2.107.0 + version: 2.108.0 '@supabase/supa-mdx-lint': specifier: 0.2.6-alpha version: 0.2.6-alpha @@ -1524,10 +1524,10 @@ importers: version: 1.6.0 '@supabase/ssr': specifier: 'catalog:' - version: 0.10.2(@supabase/supabase-js@2.107.0) + version: 0.10.2(@supabase/supabase-js@2.108.0) '@supabase/supabase-js': specifier: 'catalog:' - version: 2.107.0 + version: 2.108.0 '@tanstack/react-router': specifier: ^1.168.0 version: 1.168.18(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -1638,10 +1638,10 @@ importers: version: 10.27.0(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.5.18(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.59.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6)(supports-color@8.1.1)(webpack@5.105.4(esbuild@0.25.2)) '@supabase/ssr': specifier: 'catalog:' - version: 0.10.2(@supabase/supabase-js@2.107.0) + version: 0.10.2(@supabase/supabase-js@2.108.0) '@supabase/supabase-js': specifier: 'catalog:' - version: 2.107.0 + version: 2.108.0 '@vercel/og': specifier: ^0.6.2 version: 0.6.2 @@ -1894,13 +1894,13 @@ importers: dependencies: '@supabase/postgrest-js': specifier: 'catalog:' - version: 2.107.0 + version: 2.108.0 '@supabase/ssr': specifier: 'catalog:' - version: 0.10.2(@supabase/supabase-js@2.107.0) + version: 0.10.2(@supabase/supabase-js@2.108.0) '@supabase/supabase-js': specifier: 'catalog:' - version: 2.107.0 + version: 2.108.0 '@vueuse/core': specifier: ^14.1.0 version: 14.1.0(vue@3.5.35(typescript@6.0.2)) @@ -1946,7 +1946,7 @@ importers: version: 1.59.1 '@supabase/supabase-js': specifier: 'catalog:' - version: 2.107.0 + version: 2.108.0 cross-fetch: specifier: ^4.1.0 version: 4.1.0(encoding@0.1.13) @@ -1974,7 +1974,7 @@ importers: version: 0.18.5 '@supabase/supabase-js': specifier: 'catalog:' - version: 2.107.0 + version: 2.108.0 ai: specifier: 5.0.52 version: 5.0.52(zod@3.25.76) @@ -2065,10 +2065,10 @@ importers: dependencies: '@supabase/auth-js': specifier: 'catalog:' - version: 2.107.0 + version: 2.108.0 '@supabase/supabase-js': specifier: 'catalog:' - version: 2.107.0 + version: 2.108.0 '@types/dat.gui': specifier: ^0.7.12 version: 0.7.12 @@ -2209,7 +2209,7 @@ importers: version: link:../config next-router-mock: specifier: ^0.9.13 - version: 0.9.13(next@16.2.6(@opentelemetry/api@1.9.0)(@playwright/test@1.59.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6) + version: 0.9.13(next@16.2.6(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.59.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6) tailwindcss: specifier: 'catalog:' version: 4.2.4 @@ -2516,7 +2516,7 @@ importers: version: 0.1.6(encoding@0.1.13)(supports-color@8.1.1) '@supabase/supabase-js': specifier: 'catalog:' - version: 2.107.0 + version: 2.108.0 '@tanstack/react-table': specifier: ^8.21.3 version: 8.21.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -2697,7 +2697,7 @@ importers: version: link:../config next-router-mock: specifier: ^0.9.13 - version: 0.9.13(next@16.2.6(@opentelemetry/api@1.9.0)(@playwright/test@1.59.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6) + version: 0.9.13(next@16.2.6(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.59.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6) tailwindcss: specifier: ^4.2.4 version: 4.2.4 @@ -7672,12 +7672,12 @@ packages: '@supabase-labs/y-supabase@0.1.0': resolution: {integrity: sha512-1ItaKbcImgy7ueYfJcyVYihqCKi9RAee9MKBV8wcCqSMNsrWvw4ibhW8ai91kWsewsiWzIDXVPONgcUcxagk9g==} - '@supabase/auth-js@2.107.0': - resolution: {integrity: sha512-XA7x+WIeIvuC3GTZ2ey67QcBbGw4n+o5B7M+dMm9KT1lL3wX1B52DfEWW00WuPt/LnniJLLIn1WIm9YPtuxzKQ==} + '@supabase/auth-js@2.108.0': + resolution: {integrity: sha512-0CzVGVqHfNOhRQVEcAmu58Mex2Ce0zL3aGfyV+iFQjTK6OntLK/hLCLr/VDRX0E8/2CdsiY99L7fZ/8ys/op4w==} engines: {node: '>=20.0.0'} - '@supabase/functions-js@2.107.0': - resolution: {integrity: sha512-iMtRUmEj1KOgQd/a3MR4hnBlPnZc62DW8+z8aPpnzbxWkexEZUVL2fSgvvp15gqFg1V55e2yMGqgK+yhSQxp5w==} + '@supabase/functions-js@2.108.0': + resolution: {integrity: sha512-lqEGDzT7QBUuKYzi5lHpV/XecXT9wikzcbXMbFo6krNpSDynD1sHM8wcsfB/BAqa4NkFuy3vF4JCV8MeakV8IQ==} engines: {node: '>=20.0.0'} '@supabase/mcp-server-supabase@0.7.0': @@ -7696,12 +7696,12 @@ packages: '@supabase/phoenix@0.4.2': resolution: {integrity: sha512-YSAGnmDAfuleFCVt3CeurQZAhxRfXWeZIIkwp7NhYzQ1UwW6ePSnzsFAiUm/mbCkfoCf70QQHKW/K6RKh52a4A==} - '@supabase/postgrest-js@2.107.0': - resolution: {integrity: sha512-7ARs47/tyIjX7T0Ive20d4NY8zQYXsP5/P07jJWxffSIM2gpnSnGRnL/Fe15GPbdjsW2sTYeckHcyaoKbM6yWQ==} + '@supabase/postgrest-js@2.108.0': + resolution: {integrity: sha512-8AwTkPqowDYv/qh016CyXeZ3Ukpw6NHyfqc7DWV4afLR2hAiapf3zRKV2ZLG+//T1LK84HrR6X8VBwfgHWmNyw==} engines: {node: '>=20.0.0'} - '@supabase/realtime-js@2.107.0': - resolution: {integrity: sha512-cF2KYdR3JIn9YlWGeluY9S0G+otqTdL6hB8GzpatlEIY6fZudCcyFo6Dc3+X9tjeb+x9XcIyNAk9qhNAknjH1A==} + '@supabase/realtime-js@2.108.0': + resolution: {integrity: sha512-N3xR0u7TNr+c5wuLSU60rcfu/H/8N0WBs7iHWwjI/NxKwY3XWSyLUbpbpU8bzmL0dA/Gk9Mupri8mxKUXBW+iw==} engines: {node: '>=20.0.0'} '@supabase/shared-types@0.1.88': @@ -7715,8 +7715,8 @@ packages: peerDependencies: '@supabase/supabase-js': ^2.102.1 - '@supabase/storage-js@2.107.0': - resolution: {integrity: sha512-/X8OOVwKBn8aVKuHAGOz2yLA0d2OauqhVuy4mNtN+o7wttHOgx1/j+pqOzlsjmhOHrYykF6AJNZhs3gKZzcMUw==} + '@supabase/storage-js@2.108.0': + resolution: {integrity: sha512-zMYQmh87CId7d8i/1FIfv4fMDcXPutmIJSpoY58GLXi7M266MNzxWGNabDk4i555Oj1Nqtsu2i3Qo3rpWUXO6A==} engines: {node: '>=20.0.0'} '@supabase/supa-mdx-lint-darwin@0.2.6-alpha': @@ -7854,8 +7854,8 @@ packages: resolution: {integrity: sha512-iqJHDk/ToyxFMa/um9A5gsp9jYN7iI0cIabNq9nyBpK/Yat/J9I2IIMueQwIMy3TsG6a2qdPyUkZkuPC37SdRg==} hasBin: true - '@supabase/supabase-js@2.107.0': - resolution: {integrity: sha512-ChKzdlWVweMUUhr0U79JhMmgm1haS/C5JquaiCDr70JaGARRtjjoY9rkIheXWybXxTSNzRiQs3Sk8IAg1HS3ZA==} + '@supabase/supabase-js@2.108.0': + resolution: {integrity: sha512-AjPoimM9MZLZbddnlDBGmpZ/Tas1dNcJvuZy/VD1AfmrjBC8J2RSw6UOqR4ISLLlEioOLca/5t1crFnAxa0wRQ==} engines: {node: '>=20.0.0'} '@swc/helpers@0.5.15': @@ -23940,15 +23940,15 @@ snapshots: '@supabase-labs/y-supabase@0.1.0': dependencies: - '@supabase/supabase-js': 2.107.0 + '@supabase/supabase-js': 2.108.0 y-protocols: 1.0.7(yjs@13.6.29) yjs: 13.6.29 - '@supabase/auth-js@2.107.0': + '@supabase/auth-js@2.108.0': dependencies: tslib: 2.8.1 - '@supabase/functions-js@2.107.0': + '@supabase/functions-js@2.108.0': dependencies: tslib: 2.8.1 @@ -23970,11 +23970,11 @@ snapshots: '@supabase/phoenix@0.4.2': {} - '@supabase/postgrest-js@2.107.0': + '@supabase/postgrest-js@2.108.0': dependencies: tslib: 2.8.1 - '@supabase/realtime-js@2.107.0': + '@supabase/realtime-js@2.108.0': dependencies: '@supabase/phoenix': 0.4.2 tslib: 2.8.1 @@ -23990,12 +23990,12 @@ snapshots: - encoding - supports-color - '@supabase/ssr@0.10.2(@supabase/supabase-js@2.107.0)': + '@supabase/ssr@0.10.2(@supabase/supabase-js@2.108.0)': dependencies: - '@supabase/supabase-js': 2.107.0 + '@supabase/supabase-js': 2.108.0 cookie: 1.0.2 - '@supabase/storage-js@2.107.0': + '@supabase/storage-js@2.108.0': dependencies: iceberg-js: 0.8.1 tslib: 2.8.1 @@ -24096,13 +24096,13 @@ snapshots: '@supabase/supa-mdx-lint-win32-x64': 0.3.2 node-pty: 1.0.0 - '@supabase/supabase-js@2.107.0': + '@supabase/supabase-js@2.108.0': dependencies: - '@supabase/auth-js': 2.107.0 - '@supabase/functions-js': 2.107.0 - '@supabase/postgrest-js': 2.107.0 - '@supabase/realtime-js': 2.107.0 - '@supabase/storage-js': 2.107.0 + '@supabase/auth-js': 2.108.0 + '@supabase/functions-js': 2.108.0 + '@supabase/postgrest-js': 2.108.0 + '@supabase/realtime-js': 2.108.0 + '@supabase/storage-js': 2.108.0 '@swc/helpers@0.5.15': dependencies: @@ -31421,7 +31421,7 @@ snapshots: dependencies: js-yaml-loader: 1.2.2 - next-router-mock@0.9.13(next@16.2.6(@opentelemetry/api@1.9.0)(@playwright/test@1.59.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6): + next-router-mock@0.9.13(next@16.2.6(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.59.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6): dependencies: next: 16.2.6(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.59.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4) react: 19.2.6 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c67eb4104c3..1214fe40510 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -8,11 +8,11 @@ blockExoticSubdeps: true catalog: '@sentry/nextjs': ^10.26.0 - '@supabase/auth-js': 2.107.0 - '@supabase/postgrest-js': 2.107.0 - '@supabase/realtime-js': 2.107.0 + '@supabase/auth-js': 2.108.0 + '@supabase/postgrest-js': 2.108.0 + '@supabase/realtime-js': 2.108.0 '@supabase/ssr': 0.10.2 - '@supabase/supabase-js': 2.107.0 + '@supabase/supabase-js': 2.108.0 '@types/node': ^22.0.0 '@types/react': ^19.2.14 '@types/react-dom': ^19.2.3 From 4633992f81e14c718eec3dad096285a99d3288e6 Mon Sep 17 00:00:00 2001 From: Joshen Lim Date: Mon, 8 Jun 2026 21:24:39 +0800 Subject: [PATCH 024/134] Fix inconsistent padding in www mobile menu (#46704) ## Context As per PR title image Also resolves FE-3565 Closes mobile menu when a link is clicked ## Summary by CodeRabbit * **Improvements** * Mobile menu now closes reliably when selecting more navigation items (Modules, various Developers/Solutions links and footer links). * Enhanced link focus and interaction behavior in the mobile menu for clearer keyboard/touch feedback. * **New Features** * Navigation links can now accept optional click handlers, enabling custom onClick behavior. * **Refactor** * Internal reorganization of mobile menu styling and link composition to simplify maintenance. --- apps/www/components/Nav/MobileMenu.tsx | 81 ++++++++++++--------- apps/www/components/Nav/index.tsx | 2 +- apps/www/data/nav.tsx | 15 ++-- packages/ui-patterns/src/TextLink/index.tsx | 1 + 4 files changed, 58 insertions(+), 41 deletions(-) diff --git a/apps/www/components/Nav/MobileMenu.tsx b/apps/www/components/Nav/MobileMenu.tsx index abd64d40633..daa43631e75 100644 --- a/apps/www/components/Nav/MobileMenu.tsx +++ b/apps/www/components/Nav/MobileMenu.tsx @@ -1,12 +1,13 @@ 'use client' +import { type Menu } from '~/data/nav' import { useIsLoggedIn, useIsUserLoading } from 'common' import { AnimatePresence, domAnimation, LazyMotion, m } from 'framer-motion' import { ChevronRight } from 'lucide-react' import Link from 'next/link' import { useEffect } from 'react' import type { Dispatch, SetStateAction } from 'react' -import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Button } from 'ui' +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Button, cn } from 'ui' import { TextLink } from 'ui-patterns/TextLink' import MenuItem from './MenuItem' @@ -19,10 +20,10 @@ import { useSendTelemetryEvent } from '@/lib/telemetry' interface Props { open: boolean setOpen: Dispatch> - menu: any + menu: Menu } -const MobileMenu = ({ open, setOpen, menu }: Props) => { +export const MobileMenu = ({ open, setOpen, menu }: Props) => { const isLoggedIn = useIsLoggedIn() const isUserLoading = useIsUserLoading() const sendTelemetryEvent = useSendTelemetryEvent() @@ -50,17 +51,18 @@ const MobileMenu = ({ open, setOpen, menu }: Props) => { return () => window.removeEventListener('keydown', onKeyDown) }, [setOpen]) - const AccordionMenuItem = ({ menuItem }: any) => ( + const AccordionMenuItem = ({ menuItem }: { menuItem: Menu['primaryNav'][number] }) => ( {menuItem.title === 'Product' ? ( <> - {Object.values(menuItem.subMenu)?.map((component: any) => ( + {Object.values(menuItem.subMenu)?.map((component) => ( setOpen(false)} /> ))}
@@ -75,6 +77,7 @@ const MobileMenu = ({ open, setOpen, menu }: Props) => { href={productModule.url} description={productModule.description_short} icon={productModule.icon} + onClick={() => setOpen(false)} /> ))} @@ -90,6 +93,7 @@ const MobileMenu = ({ open, setOpen, menu }: Props) => { focus-visible:text-foreground focus-visible:ring-2 focus-visible:outline-hidden focus-visible:rounded-sm focus-visible:ring-foreground-lighter " + onClick={() => setOpen(false)} >
Features @@ -105,14 +109,14 @@ const MobileMenu = ({ open, setOpen, menu }: Props) => { ) : menuItem.title === 'Developers' ? (
- {menuItem.subMenu['navigation'].map((column: any) => ( + {menuItem.subMenu['navigation'].map((column) => (
{column.label !== 'Developers' && ( )} - {column.links.map((link: any) => ( + {column.links.map((link) => ( { label={link.text} counter={link.text === 'Careers' && jobsCount > 0 ? jobsCount : undefined} className="focus-visible:ring-offset-4 focus-visible:ring-offset-background-overlay mt-0!" + onClick={() => setOpen(false)} /> ))}
@@ -134,31 +139,34 @@ const MobileMenu = ({ open, setOpen, menu }: Props) => { url={menuItem.subMenu['footer']['support'].url} label={menuItem.subMenu['footer']['support'].text} className="focus-visible:ring-offset-4 focus-visible:ring-offset-background-overlay" + onClick={() => setOpen(false)} /> setOpen(false)} />
) : menuItem.title === 'Solutions' ? (
- {menuItem.subMenu['navigation'].map((column: any) => ( + {menuItem.subMenu['navigation'].map((column) => (
{column.label !== 'Solutions' && ( )} - {column.links.map((link: any) => ( + {column.links.map((link) => ( setOpen(false)} /> ))}
@@ -168,29 +176,38 @@ const MobileMenu = ({ open, setOpen, menu }: Props) => { ) - const Menu = () => ( - - {menu.primaryNav.map((menuItem: any) => ( - - {menuItem.hasDropdown ? ( - - + const Menu = () => { + const className = 'py-2 pl-2 pr-4 text-base font-medium text-foreground hover:bg-surface-200' + return ( + + {menu.primaryNav.map((menuItem) => ( + + {menuItem.hasDropdown ? ( + + {menuItem.title} + + + ) : ( + setOpen(false)} + > {menuItem.title} - - - - ) : ( - - {menuItem.title} - - )} - - ))} - - ) + + )} + + ))} + + ) + } return ( @@ -306,5 +323,3 @@ const MobileMenu = ({ open, setOpen, menu }: Props) => { ) } - -export default MobileMenu diff --git a/apps/www/components/Nav/index.tsx b/apps/www/components/Nav/index.tsx index f822f6bc72a..43f700548cc 100644 --- a/apps/www/components/Nav/index.tsx +++ b/apps/www/components/Nav/index.tsx @@ -23,7 +23,7 @@ import { import GitHubButton from './GitHubButton' import HamburgerButton from './HamburgerMenu' import MenuItem from './MenuItem' -import MobileMenu from './MobileMenu' +import { MobileMenu } from './MobileMenu' import RightClickBrandLogo from './RightClickBrandLogo' import useDropdownMenu from './useDropdownMenu' diff --git a/apps/www/data/nav.tsx b/apps/www/data/nav.tsx index 6c016f47cb9..c6170b4d837 100644 --- a/apps/www/data/nav.tsx +++ b/apps/www/data/nav.tsx @@ -1,44 +1,45 @@ import { DevelopersDropdown } from 'components/Nav/DevelopersDropdown' import { ProductDropdown } from 'components/Nav/ProductDropdown' import { SolutionsDropdown } from 'components/Nav/SolutionsDropdown' - import { data as DevelopersData } from 'data/Developers' import MainProductsData from 'data/MainProducts' import { navData as SolutionsData } from 'data/Solutions' +export type Menu = ReturnType + export const getMenu = () => ({ primaryNav: [ { - title: 'Product', + title: 'Product' as const, hasDropdown: true, dropdown: , dropdownContainerClassName: 'rounded-xl', subMenu: MainProductsData, }, { - title: 'Developers', + title: 'Developers' as const, hasDropdown: true, dropdown: , dropdownContainerClassName: 'rounded-xl', subMenu: DevelopersData, }, { - title: 'Solutions', + title: 'Solutions' as const, hasDropdown: true, dropdown: , dropdownContainerClassName: 'rounded-xl', subMenu: SolutionsData, }, { - title: 'Pricing', + title: 'Pricing' as const, url: '/pricing', }, { - title: 'Docs', + title: 'Docs' as const, url: '/docs', }, { - title: 'Blog', + title: 'Blog' as const, url: '/blog', }, ], diff --git a/packages/ui-patterns/src/TextLink/index.tsx b/packages/ui-patterns/src/TextLink/index.tsx index ac64fa5393c..5b7db8a1c49 100644 --- a/packages/ui-patterns/src/TextLink/index.tsx +++ b/packages/ui-patterns/src/TextLink/index.tsx @@ -12,6 +12,7 @@ interface Props { hasChevron?: boolean chevronAnimation?: 'translate' | 'fadeIn' target?: '_blank' | '_self' + onClick?: () => void } export function TextLink({ From 4c4df75cffccc62ff44a8b9b64127f590afad55c Mon Sep 17 00:00:00 2001 From: Vaibhav <117663341+7ttp@users.noreply.github.com> Date: Mon, 8 Jun 2026 19:02:00 +0530 Subject: [PATCH 025/134] fix: table list sync (#46735) smol fix :D - closes https://github.com/supabase/supabase/issues/46730 ## Summary by CodeRabbit * **Bug Fixes** * Corrected table count in footer to show the proper number and singular/plural wording when pagination is active. * Ensured table lists refresh correctly after deleting a table so paginated/infinite lists update properly. --- .../studio/components/interfaces/Database/Tables/TableList.tsx | 3 ++- apps/studio/data/tables/table-delete-mutation.ts | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/studio/components/interfaces/Database/Tables/TableList.tsx b/apps/studio/components/interfaces/Database/Tables/TableList.tsx index 80a4b5317e7..9b7f5967ef4 100644 --- a/apps/studio/components/interfaces/Database/Tables/TableList.tsx +++ b/apps/studio/components/interfaces/Database/Tables/TableList.tsx @@ -205,6 +205,7 @@ export const TableList = ({ const entities = formatAllEntities({ tables, views, materializedViews, foreignTables }).filter( (x) => visibleTypes.includes(x.type) ) + const footerCount = hasNextTablesPage ? tables.length : entities.length const { isSchemaLocked } = useIsProtectedSchema({ schema: selectedSchema }) @@ -608,7 +609,7 @@ export const TableList = ({ {isFetchingNextTablesPage ? 'Loading more tables…' - : `${entities.length} ${entities.length === 1 ? 'table' : 'tables'}${ + : `${footerCount} ${footerCount === 1 ? 'table' : 'tables'}${ hasNextTablesPage ? ' loaded' : '' }`} diff --git a/apps/studio/data/tables/table-delete-mutation.ts b/apps/studio/data/tables/table-delete-mutation.ts index dd82ce5d0b2..4fc875a6d13 100644 --- a/apps/studio/data/tables/table-delete-mutation.ts +++ b/apps/studio/data/tables/table-delete-mutation.ts @@ -57,6 +57,9 @@ export const useTableDeleteMutation = ({ await Promise.all([ queryClient.invalidateQueries({ queryKey: tableEditorKeys.tableEditor(projectRef, id) }), queryClient.invalidateQueries({ queryKey: tableKeys.list(projectRef, schema) }), + queryClient.invalidateQueries({ + queryKey: tableKeys.infiniteListPrefix(projectRef, schema), + }), queryClient.invalidateQueries({ queryKey: entityTypeKeys.list(projectRef) }), // invalidate all views from this schema queryClient.invalidateQueries({ queryKey: viewKeys.listBySchema(projectRef, schema) }), From ddba257686ff4e7bda3654c662ee382648f4a464 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Mon, 8 Jun 2026 15:55:57 +0200 Subject: [PATCH 026/134] docs: Couple of random anon leftovers (#46732) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES/ ## Summary by CodeRabbit ## Documentation * Updated project variables guidance to include publishable and secret keys alongside existing options. * Updated code examples across multiple frameworks to use publishable keys instead of anon keys. * Updated tool descriptions to reflect publishable key terminology. --- apps/docs/app/contributing/content.mdx | 2 +- apps/docs/content/guides/ai-tools/mcp.mdx | 2 +- apps/docs/content/guides/auth/third-party/clerk.mdx | 2 +- .../docs/content/guides/getting-started/quickstarts/flutter.mdx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/docs/app/contributing/content.mdx b/apps/docs/app/contributing/content.mdx index 4f03645cc87..a4c0476d5d4 100644 --- a/apps/docs/app/contributing/content.mdx +++ b/apps/docs/app/contributing/content.mdx @@ -354,7 +354,7 @@ If your image has alternate light and dark versions, or you want to make it zoom ### Project Variables -Some guides and tutorials will require that users copy their Supabase project URL and anon key. You can provide those inline if the user is signed in: +Some guides and tutorials will require that users copy their Supabase project URL and publishable or secret key. You can provide those inline if the user is signed in: ```mdx diff --git a/apps/docs/content/guides/ai-tools/mcp.mdx b/apps/docs/content/guides/ai-tools/mcp.mdx index 8e3092c2d1e..bec493599d4 100644 --- a/apps/docs/content/guides/ai-tools/mcp.mdx +++ b/apps/docs/content/guides/ai-tools/mcp.mdx @@ -52,7 +52,7 @@ The Supabase MCP server provides tools organized into feature groups. All groups ### Development - `get_project_url` - Get the API URL for a project -- `get_publishable_keys` - Get anon/public keys +- `get_publishable_keys` - Get publishable and legacy anon API keys for a project - `generate_typescript_types` - Generate TypeScript types from schema ### Edge Functions diff --git a/apps/docs/content/guides/auth/third-party/clerk.mdx b/apps/docs/content/guides/auth/third-party/clerk.mdx index 1358f8421db..25cfda14e36 100644 --- a/apps/docs/content/guides/auth/third-party/clerk.mdx +++ b/apps/docs/content/guides/auth/third-party/clerk.mdx @@ -77,7 +77,7 @@ import Supabase let supabase = SupabaseClient( supabaseURL: URL(string: "https://project-ref.supabase.io")!, - supabaseKey: "supabase.anon.key", + supabaseKey: "supabase.publishable.key", options: SupabaseClientOptions( auth: SupabaseClientOptions.AuthOptions( accessToken: { diff --git a/apps/docs/content/guides/getting-started/quickstarts/flutter.mdx b/apps/docs/content/guides/getting-started/quickstarts/flutter.mdx index c68f7cb7c67..498936ca67f 100644 --- a/apps/docs/content/guides/getting-started/quickstarts/flutter.mdx +++ b/apps/docs/content/guides/getting-started/quickstarts/flutter.mdx @@ -73,7 +73,7 @@ hideToc: true await Supabase.initialize( url: 'YOUR_SUPABASE_URL', - anonKey: 'YOUR_SUPABASE_PUBLISHABLE_KEY', + publishableKey: 'YOUR_SUPABASE_PUBLISHABLE_KEY', ); runApp(MyApp()); } From a491936f7983b7b1b584984d8310747013a2e1dd Mon Sep 17 00:00:00 2001 From: Gildas Garcia <1122076+djhi@users.noreply.github.com> Date: Mon, 8 Jun 2026 15:59:13 +0200 Subject: [PATCH 027/134] feat: allow to resync production branches (#46723) ## Problem 1. Users can't resync/rebase production branches but those could get stuck too 2. We currently check for branches health state to allow resync/rebase, preventing to unblock some cases ## Solution 1. Add an menu item to resync/rebase production branches 2. Remove the unnecessary health checks ## Summary by CodeRabbit * **New Features** * Added resync/retrigger for production (main) branches with a confirmation dialog and loading state. * **Improvements** * Simplified and clarified branch action tooltip messaging. * Refined availability and disabled logic for branch actions (permission and in-flight handling). * Improved UX for switching between preview and persistent branches, including adjusted messaging for upgrade entitlements. --- .../interfaces/BranchManagement/Overview.tsx | 131 ++++++++++++------ 1 file changed, 89 insertions(+), 42 deletions(-) diff --git a/apps/studio/components/interfaces/BranchManagement/Overview.tsx b/apps/studio/components/interfaces/BranchManagement/Overview.tsx index bec2163e23b..2ea963c738f 100644 --- a/apps/studio/components/interfaces/BranchManagement/Overview.tsx +++ b/apps/studio/components/interfaces/BranchManagement/Overview.tsx @@ -365,7 +365,7 @@ const PreviewBranchActions = ({ <> { e.stopPropagation() setShowConfirmRetriggersModal(true) @@ -379,9 +379,7 @@ const PreviewBranchActions = ({ side: 'left', text: !canUpdateBranches ? `You need additional permissions to ${branch.git_branch ? 'resync' : 'rebase'} branches` - : !isBranchActiveHealthy - ? `Branch is still initializing. Please wait for it to become healthy before ${branch.git_branch ? 'resyncing' : 'rebasing'}.` - : undefined, + : undefined, }, }} > @@ -409,46 +407,43 @@ const PreviewBranchActions = ({ > Reset branch + { + e.stopPropagation() + setShowBranchModeSwitch(true) + }} + onClick={(e) => { + e.stopPropagation() + setShowBranchModeSwitch(true) + }} + tooltip={{ + content: { + side: 'left', + text: !isBranchActiveHealthy + ? 'Branch is still initializing. Please wait for it to become healthy before switching.' + : !branch.persistent && !hasAccessToPersistentBranching + ? 'Upgrade your plan to access persistent branches' + : undefined, + }, + }} + > + {branch.persistent ? ( + <> + Switch to preview + + ) : ( + <> + Switch to persistent + + )} + )} - {!branch.deletion_scheduled_at && ( - { - e.stopPropagation() - setShowBranchModeSwitch(true) - }} - onClick={(e) => { - e.stopPropagation() - setShowBranchModeSwitch(true) - }} - tooltip={{ - content: { - side: 'left', - text: !isBranchActiveHealthy - ? 'Branch is still initializing. Please wait for it to become healthy before switching.' - : !branch.persistent && !hasAccessToPersistentBranching - ? 'Upgrade your plan to access persistent branches' - : undefined, - }, - }} - > - {branch.persistent ? ( - <> - Switch to preview - - ) : ( - <> - Switch to persistent - - )} - - )} - {/* Create PR if applicable */} {branch.git_branch && branch.pr_number === undefined && ( @@ -581,12 +576,27 @@ const PreviewBranchActions = ({ // Actions for main (production) branch const MainBranchActions = ({ branch, repo }: { branch: Branch; repo: string }) => { - const { ref: projectRef } = useParams() + const { project_ref: branchRef, parent_project_ref: projectRef } = branch + const { can: canUpdateBranches } = useAsyncCheckPermissions( PermissionAction.UPDATE, 'preview_branches' ) + const { mutate: branchPushMutate, isPending: isRetriggering } = useBranchPushMutation({ + onSuccess() { + toast.success('Success! Please allow a few minutes for the branch to update.') + setShowConfirmRetriggersModal(false) + }, + onError: (data) => { + toast.error(`Failed to trigger workflow: ${data.message}`) + }, + }) const [showEditBranchModal, setShowEditBranchModal] = useState(false) + const [showConfirmRetriggersModal, setShowConfirmRetriggersModal] = useState(false) + + const onRetriggerBranch = () => { + branchPushMutate({ branchRef, projectRef }) + } return ( <> @@ -611,6 +621,30 @@ const MainBranchActions = ({ branch, repo }: { branch: Branch; repo: string }) = Edit Branch )} + {branch.git_branch ? ( + { + e.stopPropagation() + setShowConfirmRetriggersModal(true) + }} + onClick={(e) => { + e.stopPropagation() + setShowConfirmRetriggersModal(true) + }} + tooltip={{ + content: { + side: 'left', + text: !canUpdateBranches + ? `You need additional permissions to resync branches` + : undefined, + }, + }} + > + Resync branch + + ) : null} @@ -619,6 +653,19 @@ const MainBranchActions = ({ branch, repo }: { branch: Branch; repo: string }) = visible={showEditBranchModal} onClose={() => setShowEditBranchModal(false)} /> + setShowConfirmRetriggersModal(false)} + onConfirm={onRetriggerBranch} + > +

+ This will re-run all steps of the workflow based on the latest git branch state. +

+
) } From f5dadafb688734b4eab67e59cf5de8aa782ab7d4 Mon Sep 17 00:00:00 2001 From: Gildas Garcia <1122076+djhi@users.noreply.github.com> Date: Mon, 8 Jun 2026 16:01:32 +0200 Subject: [PATCH 028/134] fix: compute section badges design on mobile (#46724) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before: image After: image ## Summary by CodeRabbit * **Style** * Updated the pricing callout to use a responsive layout so the price and accompanying text stack on small screens and align side-by-side on larger screens for improved spacing and readability. * Adjusted the price badge to prevent text wrapping, ensuring the “$10” label remains visible and consistent across devices. * Tuned margins and vertical spacing for better alignment across breakpoints. --- apps/www/components/Pricing/PricingComputeSection.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/www/components/Pricing/PricingComputeSection.tsx b/apps/www/components/Pricing/PricingComputeSection.tsx index b91d886c388..09e2e38bb8f 100644 --- a/apps/www/components/Pricing/PricingComputeSection.tsx +++ b/apps/www/components/Pricing/PricingComputeSection.tsx @@ -116,14 +116,14 @@ const PricingComputeSection = () => {

-
+

- + Starts from $10/month

-

+

Scale compute up to
64 cores and 256 GB RAM

From bf26acaa32817d5a893d2b06e932e01b210005ba Mon Sep 17 00:00:00 2001 From: Pedro Rodrigues <44656907+Rodriguespn@users.noreply.github.com> Date: Mon, 8 Jun 2026 15:33:02 +0100 Subject: [PATCH 029/134] fix(docs): update Gemini CLI extension repo URL (#46736) ## Summary Update Gemini CLI Extension repo URL from https://github.com/supabase-community/gemini-extension to https://github.com/supabase-community/supabase-plugin. Closes [AI-807](https://linear.app/supabase/issue/AI-807/update-gemini-cli-installation-command-with-the-new-github-repo-in-our) ## Summary by CodeRabbit * **Documentation** * Updated Gemini CLI plugin configuration to reference the Supabase community plugin repository * Updated installation instructions and repository links to reflect the new plugin location Co-authored-by: Claude Sonnet 4.6 --- apps/docs/features/ui/AgentPluginsPanel.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/docs/features/ui/AgentPluginsPanel.tsx b/apps/docs/features/ui/AgentPluginsPanel.tsx index bc7ac349273..33518664e6d 100644 --- a/apps/docs/features/ui/AgentPluginsPanel.tsx +++ b/apps/docs/features/ui/AgentPluginsPanel.tsx @@ -38,7 +38,7 @@ const PLUGIN_CLIENTS: PluginClient[] = [ key: 'gemini-cli', label: 'Gemini CLI', icon: 'gemini-cli', - repoUrl: 'https://github.com/supabase-community/gemini-extension', + repoUrl: 'https://github.com/supabase-community/supabase-plugin', docsUrl: 'https://geminicli.com/docs/extensions/', }, { @@ -151,7 +151,7 @@ function PluginInstructions({ client }: { client: PluginClient }) { your terminal.

You can also find the extension in the{' '} Date: Mon, 8 Jun 2026 18:09:08 +0300 Subject: [PATCH 030/134] docs: fix invalid syntax and wrong identifiers in code examples (#46694) Reading through the guides and troubleshooting docs I found a set of code examples that don't parse or run as written. Each is a small, self-contained fix: - **troubleshooting/postgres-logs**: the `regexp_contains(...)` call was missing its closing parenthesis. - **troubleshooting/rls-performance**: the PL/pgSQL `return` statement was missing its terminating semicolon. - **troubleshooting/supavisor-faq**: the `CREATE USER ... WITH PASSWORD` string literal was unterminated (missing closing quote). - **troubleshooting/google-auth-fails**: missing comma between `provider` and `options` in the `signInWithOAuth` object literal. - **integrations/supabase-for-platforms**, **database/extensions/pg_graphql**, **deployment/branching/working-with-branches**: missing commas between JSON properties. - **database/extensions/pgjwt**: the default algorithm was written `'HSA256'`; the real default is `'HS256'` (used in both `sign` and `verify`). - **auth/auth-email-passwordless** (Dart): `signinwithotp` should be `signInWithOtp`. - **auth/third-party/firebase-auth**: `async function setRoleCustomClaim() => {` mixed a function declaration with arrow syntax. - **storage/management/copy-move-objects**: the storage helper is `storage.foldername(name)`, not `storage.folder(name)`. - **troubleshooting/hsnw-index**: prose referred to `maintance_work_mem`; the setting is `maintenance_work_mem` (the SQL in the same file spells it correctly). - **troubleshooting/pgcron-debugging**: a stray double quote inside the `cron.job_run_details` code span. 13 files, all one-line fixes. Happy to split if you'd prefer. ## Summary by CodeRabbit * **Documentation** * Corrected code examples across authentication, database, storage, and troubleshooting guides * Fixed method naming and syntax errors in code snippets (Dart auth, Node.js Firebase, SQL functions) * Updated API signatures and variable names for accuracy * Improved JSON formatting in example payloads * Corrected typos in documentation text --------- Co-authored-by: Chris Chinchilla --- apps/docs/content/guides/auth/auth-email-passwordless.mdx | 2 +- apps/docs/content/guides/auth/third-party/firebase-auth.mdx | 2 +- apps/docs/content/guides/database/extensions/pg_graphql.mdx | 2 +- apps/docs/content/guides/database/extensions/pgjwt.mdx | 4 ++-- .../guides/deployment/branching/working-with-branches.mdx | 2 +- .../content/guides/integrations/supabase-for-platforms.mdx | 2 +- .../content/guides/storage/management/copy-move-objects.mdx | 2 +- .../google-auth-fails-for-some-users-XcFXEu.mdx | 5 +++-- ...how-to-interpret-and-explore-the-postgres-logs-OuCIOj.mdx | 2 +- ...vector-lookup-speeds-by-applying-an-hsnw-index-ohLHUM.mdx | 2 +- .../troubleshooting/pgcron-debugging-guide-n1KTaz.mdx | 2 +- .../rls-performance-and-best-practices-Z5Jjwv.mdx | 2 +- apps/docs/content/troubleshooting/supavisor-faq-YyP5tI.mdx | 2 +- 13 files changed, 16 insertions(+), 15 deletions(-) diff --git a/apps/docs/content/guides/auth/auth-email-passwordless.mdx b/apps/docs/content/guides/auth/auth-email-passwordless.mdx index 647211150ba..34e48a8b2b4 100644 --- a/apps/docs/content/guides/auth/auth-email-passwordless.mdx +++ b/apps/docs/content/guides/auth/auth-email-passwordless.mdx @@ -87,7 +87,7 @@ Read the [Deep Linking Documentation](/docs/guides/auth/native-mobile-deep-linki ```dart Future signInWithEmail() async { - final AuthResponse res = await supabase.auth.signinwithotp(email: 'valid.email@supabase.io'); + final AuthResponse res = await supabase.auth.signInWithOtp(email: 'valid.email@supabase.io'); } ``` diff --git a/apps/docs/content/guides/auth/third-party/firebase-auth.mdx b/apps/docs/content/guides/auth/third-party/firebase-auth.mdx index b1e9f4380cf..fb9d28422b0 100644 --- a/apps/docs/content/guides/auth/third-party/firebase-auth.mdx +++ b/apps/docs/content/guides/auth/third-party/firebase-auth.mdx @@ -338,7 +338,7 @@ const { initializeApp } = require('firebase-admin/app'); const { getAuth } = require('firebase-admin/auth'); initializeApp(); -async function setRoleCustomClaim() => { +async function setRoleCustomClaim() { let nextPageToken = undefined do { diff --git a/apps/docs/content/guides/database/extensions/pg_graphql.mdx b/apps/docs/content/guides/database/extensions/pg_graphql.mdx index 389dc09ddd6..ce5845773f0 100644 --- a/apps/docs/content/guides/database/extensions/pg_graphql.mdx +++ b/apps/docs/content/guides/database/extensions/pg_graphql.mdx @@ -90,7 +90,7 @@ returning the JSON "edges": [ { "node": { - "id": 1 + "id": 1, "name": "My Blog" } } diff --git a/apps/docs/content/guides/database/extensions/pgjwt.mdx b/apps/docs/content/guides/database/extensions/pgjwt.mdx index fb0283e5dce..a77f55297df 100644 --- a/apps/docs/content/guides/database/extensions/pgjwt.mdx +++ b/apps/docs/content/guides/database/extensions/pgjwt.mdx @@ -55,8 +55,8 @@ It's good practice to create the extension within a separate schema (like `exten ## API -- [`sign(payload json, secret text, algorithm text default 'HSA256')`](https://github.com/michelp/pgjwt#usage): Signs a JWT containing _payload_ with _secret_ using _algorithm_. -- [`verify(token text, secret text, algorithm text default 'HSA256')`](https://github.com/michelp/pgjwt#usage): Decodes a JWT _token_ that was signed with _secret_ using _algorithm_. +- [`sign(payload json, secret text, algorithm text default 'HS256')`](https://github.com/michelp/pgjwt#usage): Signs a JWT containing _payload_ with _secret_ using _algorithm_. +- [`verify(token text, secret text, algorithm text default 'HS256')`](https://github.com/michelp/pgjwt#usage): Decodes a JWT _token_ that was signed with _secret_ using _algorithm_. Where: diff --git a/apps/docs/content/guides/deployment/branching/working-with-branches.mdx b/apps/docs/content/guides/deployment/branching/working-with-branches.mdx index 15ef3b1c6bf..ecdceb08658 100644 --- a/apps/docs/content/guides/deployment/branching/working-with-branches.mdx +++ b/apps/docs/content/guides/deployment/branching/working-with-branches.mdx @@ -19,7 +19,7 @@ You can subscribe to webhook notifications when an action run completes on a per "details_url": "https://supabase.com/dashboard/project/xuqpsshjxdecrwdyuxvs/branches", "action_run": { "id": "d5f8b4298d0a4d37b99e255c7837e7af", - "created_at": "2025-10-17T02:27:10.133329324Z" + "created_at": "2025-10-17T02:27:10.133329324Z", "steps": [ { "name": "clone", diff --git a/apps/docs/content/guides/integrations/supabase-for-platforms.mdx b/apps/docs/content/guides/integrations/supabase-for-platforms.mdx index e1204f22222..c1ac2b31012 100644 --- a/apps/docs/content/guides/integrations/supabase-for-platforms.mdx +++ b/apps/docs/content/guides/integrations/supabase-for-platforms.mdx @@ -160,7 +160,7 @@ curl 'https://api.supabase.com/v1/projects/{ref}/branches' \ --data '{ "branch_name": "DEV", "secrets": { - "STRIPE_SECRET_KEY":"sk_test_123..." + "STRIPE_SECRET_KEY":"sk_test_123...", "STRIPE_PUBLISHABLE_KEY":"pk_test_123..." } }' diff --git a/apps/docs/content/guides/storage/management/copy-move-objects.mdx b/apps/docs/content/guides/storage/management/copy-move-objects.mdx index 9103fdbed7d..844bdbf6d52 100644 --- a/apps/docs/content/guides/storage/management/copy-move-objects.mdx +++ b/apps/docs/content/guides/storage/management/copy-move-objects.mdx @@ -94,7 +94,7 @@ on storage.objects for insert to authenticated with check ( - (storage.folder(name))[1] = (select auth.uid()) + (storage.foldername(name))[1] = (select auth.uid()) ); create policy "User can update their own objects (in any buckets)" diff --git a/apps/docs/content/troubleshooting/google-auth-fails-for-some-users-XcFXEu.mdx b/apps/docs/content/troubleshooting/google-auth-fails-for-some-users-XcFXEu.mdx index b4deff01c56..c83f76463f9 100644 --- a/apps/docs/content/troubleshooting/google-auth-fails-for-some-users-XcFXEu.mdx +++ b/apps/docs/content/troubleshooting/google-auth-fails-for-some-users-XcFXEu.mdx @@ -42,9 +42,10 @@ It is happening because some Google Suite requires the explicit request of email ```js const { data, error } = await supabase.auth.signInWithOAuth({ - provider: 'google' + provider: 'google', options: { - scopes: 'https://www.googleapis.com/auth/userinfo.email' + scopes: 'https://www.googleapis.com/auth/userinfo.email', + }, } }) ``` diff --git a/apps/docs/content/troubleshooting/how-to-interpret-and-explore-the-postgres-logs-OuCIOj.mdx b/apps/docs/content/troubleshooting/how-to-interpret-and-explore-the-postgres-logs-OuCIOj.mdx index 3a0ac0ea1e1..d4711a6198c 100644 --- a/apps/docs/content/troubleshooting/how-to-interpret-and-explore-the-postgres-logs-OuCIOj.mdx +++ b/apps/docs/content/troubleshooting/how-to-interpret-and-explore-the-postgres-logs-OuCIOj.mdx @@ -136,7 +136,7 @@ When exploring the logs for atypical behavior, it's often strategic to filter ou ...query where -- Excluding routine events related to cron, PgBouncer, checkpoints, and successful connections - not regexp_contains(event_message, '^cron|PgBouncer|checkpoint|connection received|authenticated|authorized'; + not regexp_contains(event_message, '^cron|PgBouncer|checkpoint|connection received|authenticated|authorized'); ``` ### By timeframe diff --git a/apps/docs/content/troubleshooting/increase-vector-lookup-speeds-by-applying-an-hsnw-index-ohLHUM.mdx b/apps/docs/content/troubleshooting/increase-vector-lookup-speeds-by-applying-an-hsnw-index-ohLHUM.mdx index 0557d1b156a..6c5e0f6365b 100644 --- a/apps/docs/content/troubleshooting/increase-vector-lookup-speeds-by-applying-an-hsnw-index-ohLHUM.mdx +++ b/apps/docs/content/troubleshooting/increase-vector-lookup-speeds-by-applying-an-hsnw-index-ohLHUM.mdx @@ -58,7 +58,7 @@ If an address is returned, you should use your direct connection string found on **3. Increase memory for index creation (optional)** -The `maintance_work_mem` variable limits the maximum amount of memory that can be used by maintenance operations, such as vacuuming, altering, and indexing tables. In your session you should try to set it to a reasonably high value: +The `maintenance_work_mem` variable limits the maximum amount of memory that can be used by maintenance operations, such as vacuuming, altering, and indexing tables. In your session you should try to set it to a reasonably high value: ```sql set maintenance_work_mem to ; -- '#GB' diff --git a/apps/docs/content/troubleshooting/pgcron-debugging-guide-n1KTaz.mdx b/apps/docs/content/troubleshooting/pgcron-debugging-guide-n1KTaz.mdx index f6da4a213cf..7c027809550 100644 --- a/apps/docs/content/troubleshooting/pgcron-debugging-guide-n1KTaz.mdx +++ b/apps/docs/content/troubleshooting/pgcron-debugging-guide-n1KTaz.mdx @@ -58,7 +58,7 @@ If the query does not return a row, the worker has died. To revive it, you must ### Check the `cron.job_run_details` table for more information -pg_cron creates logs in its own table `cron.job_run_details"`. The below query checks for issues from the past 5 days : +pg_cron creates logs in its own table `cron.job_run_details`. The below query checks for issues from the past 5 days : ```sql SELECT * diff --git a/apps/docs/content/troubleshooting/rls-performance-and-best-practices-Z5Jjwv.mdx b/apps/docs/content/troubleshooting/rls-performance-and-best-practices-Z5Jjwv.mdx index a2ef2eaa839..ec8820dff09 100644 --- a/apps/docs/content/troubleshooting/rls-performance-and-best-practices-Z5Jjwv.mdx +++ b/apps/docs/content/troubleshooting/rls-performance-and-best-practices-Z5Jjwv.mdx @@ -85,7 +85,7 @@ CREATE OR REPLACE FUNCTION has_role() RETURNS boolean as $$ begin - return exists (select 1 from roles_table where auth.uid() = user_id and role = 'good_role') + return exists (select 1 from roles_table where auth.uid() = user_id and role = 'good_role'); end; $$ language plpgsql security definer; ``` diff --git a/apps/docs/content/troubleshooting/supavisor-faq-YyP5tI.mdx b/apps/docs/content/troubleshooting/supavisor-faq-YyP5tI.mdx index dbb15fb1d1b..981a0024565 100644 --- a/apps/docs/content/troubleshooting/supavisor-faq-YyP5tI.mdx +++ b/apps/docs/content/troubleshooting/supavisor-faq-YyP5tI.mdx @@ -103,7 +103,7 @@ CREATE DATABASE another_database; Similarly, a database can have many database users, but most people just rely on the default user `postgres`. ```sql -CREATE USER postgres WITH PASSWORD 'super-secret-password; +CREATE USER postgres WITH PASSWORD 'super-secret-password'; CREATE USER some_new_user WITH PASSWORD 'password'; ``` From d8b7dd5466f8c522e55fd48d3fccb67bbf0cd2a3 Mon Sep 17 00:00:00 2001 From: "supabase-supabase-autofixer[bot]" <248690971+supabase-supabase-autofixer[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 09:57:14 -0600 Subject: [PATCH 031/134] [bot] Decrease ESLint ratchet baselines (#46700) Automated weekly decrease of ESLint ratchet baselines. Co-authored-by: github-actions[bot] --- .../studio/.github/eslint-rule-baselines.json | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/apps/studio/.github/eslint-rule-baselines.json b/apps/studio/.github/eslint-rule-baselines.json index 8ce74e19536..37f87aa30ff 100644 --- a/apps/studio/.github/eslint-rule-baselines.json +++ b/apps/studio/.github/eslint-rule-baselines.json @@ -1,9 +1,9 @@ { "rules": { - "react-hooks/exhaustive-deps": 175, + "react-hooks/exhaustive-deps": 174, "import/no-anonymous-default-export": 57, - "@tanstack/query/exhaustive-deps": 12, - "@typescript-eslint/no-explicit-any": 983, + "@tanstack/query/exhaustive-deps": 9, + "@typescript-eslint/no-explicit-any": 968, "no-restricted-imports": 0, "no-restricted-exports": 240, "react/no-unstable-nested-components": 47 @@ -65,7 +65,7 @@ "components/interfaces/SQLEditor/MonacoEditor.tsx": 1, "components/interfaces/SQLEditor/MoveQueryModal.tsx": 1, "components/interfaces/SQLEditor/OngoingQueriesPanel.tsx": 1, - "components/interfaces/SQLEditor/SQLEditor.tsx": 3, + "components/interfaces/SQLEditor/SQLEditor.tsx": 2, "components/interfaces/SQLEditor/UtilityPanel/SavingIndicator.tsx": 1, "components/interfaces/Settings/Addons/CustomDomainSidePanel.tsx": 1, "components/interfaces/Settings/Addons/IPv4SidePanel.tsx": 1, @@ -123,6 +123,7 @@ "hooks/misc/useSchemaQueryState.ts": 1, "hooks/misc/useTrackExperimentExposure.ts": 1, "hooks/misc/useUpgradePrompt.tsx": 1, + "lib/telemetry/track.ts": 1, "pages/forgot-password-mfa.tsx": 1, "pages/integrations/vercel/[slug]/deploy-button/new-project.tsx": 1, "pages/integrations/vercel/install.tsx": 1, @@ -134,7 +135,6 @@ "pages/project/[ref]/settings/jwt/legacy.tsx": 1, "pages/project/[ref]/sql/examples.tsx": 1, "pages/project/[ref]/sql/templates.tsx": 1, - "pages/sign-in-mfa.tsx": 1, "state/role-impersonation-state.tsx": 1, "state/sidebar-manager-state.tsx": 1, "state/table-editor-table.tsx": 1 @@ -199,16 +199,13 @@ "pages/api/v1/projects/[ref]/types/typescript.ts": 1 }, "@tanstack/query/exhaustive-deps": { - "components/interfaces/Reports/SharedAPIReport/SharedAPIReport.constants.ts": 1, "components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx": 1, "components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.utils.tsx": 2, "data/branches/branch-diff-query.ts": 1, "data/database/foreign-key-constraints-query.ts": 1, "data/database/schemas-query.ts": 1, "data/entity-types/entity-types-infinite-query.ts": 1, - "data/tables/tables-query.ts": 2, - "hooks/analytics/useDbQuery.tsx": 1, - "hooks/analytics/useSingleLog.tsx": 1 + "data/tables/tables-query.ts": 2 }, "@typescript-eslint/no-explicit-any": { "components/grid/SupabaseGrid.tsx": 1, @@ -235,7 +232,6 @@ "components/interfaces/Auth/AuthProvidersForm/index.tsx": 7, "components/interfaces/Auth/AuthProvidersFormValidation.tsx": 2, "components/interfaces/Auth/BasicAuthSettingsForm.tsx": 1, - "components/interfaces/Auth/EmailTemplates/EmailTemplates.tsx": 1, "components/interfaces/Auth/Overview/OverviewTable.tsx": 1, "components/interfaces/Auth/Overview/OverviewUsage.constants.ts": 1, "components/interfaces/Auth/PerformanceSettingsForm.tsx": 2, @@ -250,7 +246,7 @@ "components/interfaces/Auth/RedirectUrls/RedirectUrlList.tsx": 1, "components/interfaces/Auth/SessionsAuthSettingsForm/SessionsAuthSettingsForm.tsx": 2, "components/interfaces/Auth/SiteUrl/SiteUrl.tsx": 1, - "components/interfaces/Auth/SmtpForm/SmtpForm.tsx": 3, + "components/interfaces/Auth/SmtpForm/SmtpForm.tsx": 2, "components/interfaces/Auth/Users/UserLogs.tsx": 1, "components/interfaces/Auth/Users/UserPanel.tsx": 1, "components/interfaces/Auth/Users/Users.utils.tsx": 5, @@ -436,11 +432,8 @@ "components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/ForeignKeysManagement/ForeignKeyRow.tsx": 1, "components/interfaces/TableGridEditor/TableDefinition.tsx": 3, "components/interfaces/TableGridEditor/TableEntity.utils.ts": 1, - "components/interfaces/UnifiedLogs/ServiceFlow/components/blocks/PostgresFlowDetail.tsx": 2, - "components/interfaces/UnifiedLogs/ServiceFlow/components/blocks/ResponseCompletedBlock.tsx": 1, - "components/interfaces/UnifiedLogs/ServiceFlow/components/shared/CollapsibleSection.tsx": 4, + "components/interfaces/UnifiedLogs/ServiceFlow/components/PostgresFlowDetail.tsx": 2, "components/interfaces/UnifiedLogs/ServiceFlow/components/shared/FieldWithSeeMore.tsx": 4, - "components/interfaces/UnifiedLogs/ServiceFlow/components/shared/TimelineStep.tsx": 1, "components/interfaces/UnifiedLogs/ServiceFlow/config/fieldHelpers.ts": 3, "components/interfaces/UnifiedLogs/ServiceFlow/types.ts": 10, "components/interfaces/UnifiedLogs/ServiceFlow/utils/storageUtils.ts": 3, @@ -590,7 +583,6 @@ "hooks/misc/withAuth.tsx": 1, "hooks/ui/useClickedOutside.ts": 2, "hooks/ui/useFlag.ts": 1, - "hooks/useStaticEffectEvent.ts": 1, "instrumentation-client.ts": 3, "lib/ai/generate-assistant-response.ts": 2, "lib/ai/model.ts": 2, From 750a339ca902cbfeaf47a3ba9b613211141863c5 Mon Sep 17 00:00:00 2001 From: Naren <41925131+narendraio@users.noreply.github.com> Date: Mon, 8 Jun 2026 21:27:25 +0530 Subject: [PATCH 032/134] docs(storage): clarify imgproxy is bundled in the self-hosted stack (#46527) --- .../guides/storage/serving/image-transformations.mdx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/docs/content/guides/storage/serving/image-transformations.mdx b/apps/docs/content/guides/storage/serving/image-transformations.mdx index fd68c3a2d00..734e2fa391f 100644 --- a/apps/docs/content/guides/storage/serving/image-transformations.mdx +++ b/apps/docs/content/guides/storage/serving/image-transformations.mdx @@ -683,7 +683,13 @@ response = supabase.storage.from_('bucket').download( ## Self hosting -Our solution to image resizing and optimization can be self-hosted as with any other Supabase product. Under the hood we use [imgproxy](https://imgproxy.net/) +Our solution to image resizing and optimization can be self-hosted as with any other Supabase product. Under the hood we use [imgproxy](https://imgproxy.net/). + + + +If you run the official self-hosted stack from the [`supabase/supabase`](https://github.com/supabase/supabase/tree/master/docker) Docker Compose setup, an `imgproxy` service is **already included** and wired up to the `storage` service for you (the `storage` service sets `ENABLE_IMAGE_TRANSFORMATION: "true"` and `IMGPROXY_URL: http://imgproxy:5001`). You only need the steps below if you run `storage-api` outside of that Compose stack and have to provide your own imgproxy container. + + #### imgproxy configuration: From 97c5db721814b111e36967e2276d611ae0586653 Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Mon, 8 Jun 2026 12:08:43 -0400 Subject: [PATCH 033/134] chore: regenerate marketplace types (#46746) Regenerates types for marketplace schema bindings to remove deprecated RPC functions. --- packages/common/marketplace.types.ts | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/packages/common/marketplace.types.ts b/packages/common/marketplace.types.ts index 225f7370b9c..2c27e642bd4 100644 --- a/packages/common/marketplace.types.ts +++ b/packages/common/marketplace.types.ts @@ -125,22 +125,7 @@ export type Database = { } } Functions: { - get_redirect_url: { - Args: { - p_listing_id: string - p_organization_slug: string - p_project_id: string - } - Returns: Json - } - get_redirect_url_by_slug: { - Args: { - p_listing_slug: string - p_organization_slug: string - p_project_id: string - } - Returns: Json - } + [_ in never]: never } Enums: { [_ in never]: never From ddf8569533142e4aecb78b056e7879950a0595ec Mon Sep 17 00:00:00 2001 From: Vaibhav <117663341+7ttp@users.noreply.github.com> Date: Mon, 8 Jun 2026 22:15:02 +0530 Subject: [PATCH 034/134] fix: toggle regression (#46751) - Broken by: #45504 - closes: #46744 ## Summary by CodeRabbit * **Style** * Refined the footer layout to improve alignment of view and table toggle controls. --- apps/studio/components/grid/components/footer/Footer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/studio/components/grid/components/footer/Footer.tsx b/apps/studio/components/grid/components/footer/Footer.tsx index 77a81ff1e9f..5ecd561dbd2 100644 --- a/apps/studio/components/grid/components/footer/Footer.tsx +++ b/apps/studio/components/grid/components/footer/Footer.tsx @@ -30,7 +30,7 @@ export const Footer: React.FC = ({ enableForeignRowsQuery = true }: {selectedView === 'data' && } -
+
{(isViewSelected || isTableSelected) && ( Date: Mon, 8 Jun 2026 22:15:39 +0530 Subject: [PATCH 035/134] fix: keep role view (#46426) ## TL;DR fixes export hydration so it stays under the active impersonated role in table Editor ## Example: while viewing as `anon` | Before | After | | --- | --- | | before: hydration query wrapped
with anon impersonation | after: plain select without
impersonation wrapper | PS: The `Export` path was skipping the active impersonation context and issuing the query without the `anon` role wrapper ## ref - closes #46423 ## Summary by CodeRabbit * **Bug Fixes** * Export functionality now includes role impersonation context for both full dataset and selected row exports, ensuring consistent behavior across all export operations. [![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46426?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) --- apps/studio/components/grid/components/header/Header.tsx | 8 +++++++- .../layouts/TableEditorLayout/ExportAllRows.tsx | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/studio/components/grid/components/header/Header.tsx b/apps/studio/components/grid/components/header/Header.tsx index efaf1c26acc..0ea1eb2e2fe 100644 --- a/apps/studio/components/grid/components/header/Header.tsx +++ b/apps/studio/components/grid/components/header/Header.tsx @@ -259,11 +259,17 @@ const RowHeader = ({ tableQueriesEnabled = true }: RowHeaderProps) => { } const exportParams = snap.allRowsSelected - ? ({ type: 'fetch_all', filters, sorts } as const) + ? ({ + type: 'fetch_all', + filters, + sorts, + roleImpersonationState: roleImpersonationState as RoleImpersonationState, + } as const) : ({ type: 'provided_rows', table: snap.table, rows: allRows.filter((x) => snap.selectedRows.has(x.idx)), + roleImpersonationState: roleImpersonationState as RoleImpersonationState, } as const) const { exportCsv, confirmationModal: exportCsvConfirmationModal } = useExportAllRowsAsCsv( diff --git a/apps/studio/components/layouts/TableEditorLayout/ExportAllRows.tsx b/apps/studio/components/layouts/TableEditorLayout/ExportAllRows.tsx index 259cfbb931d..c20db337c0e 100644 --- a/apps/studio/components/layouts/TableEditorLayout/ExportAllRows.tsx +++ b/apps/studio/components/layouts/TableEditorLayout/ExportAllRows.tsx @@ -259,6 +259,7 @@ type UseExportAllRowsParams = type: 'provided_rows' table: SupaTable rows: Record[] + roleImpersonationState?: RoleImpersonationState } )) @@ -297,6 +298,7 @@ export const useExportAllRowsGeneric = ( table: params.table, projectRef, connectionString, + roleImpersonationState: params.roleImpersonationState, }) if (hydrated.status === 'no_primary_key') { return { From 35df5703421a60b94fd71e496f918f07f227ac3a Mon Sep 17 00:00:00 2001 From: Danny White <3104761+dnywh@users.noreply.github.com> Date: Mon, 8 Jun 2026 10:51:04 -0600 Subject: [PATCH 036/134] feat(studio): move /authorize to connect interstitial (#46359) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > [!CAUTION] > The `do-not-merge` label has been applied because this contains mocks for easier review and testing. I'll remove those mocks before merging. ## What kind of change does this PR introduce? Feature. Part of the shared Connect UI (interstitial) rollout. Previous slices: #46058, #45909, #45862. ## What is the current behavior? The `/authorize` MCP/OAuth consent screen uses the old `Card`/`Alert` layout. ## What is the new behavior? - Wraps all `/authorize` states in `InterstitialLayout` (the shared full-screen centered card used across Connect flows) - Shows a quiet footnote below the Cancel button ("Authorizing will redirect you to \") for non-localhost redirect URIs, so users can verify the destination before approving. No extra friction for localhost flows (local MCP servers) | Before | After | | --- | --- | | Authorize API access
Supabase-F6C3747A-5077-43D8-A509-3E16B1DDC168 | Authorize API Access
Supabase-FE6FD8B3-1159-4EA5-94D7-EA5CEA7A25F3 | | Authorize API access
Supabase-86742351-3521-4B62-AF87-403CB7E7F4F5 | Authorize Cursor
Supabase-B665B4A4-600F-462B-8C97-84B171EC3103 | | Authorize API access
Supabase-C73DC3D0-8646-4E6E-A259-3E84AE46DAF2 | Authorize Cursor
Supabase-FEA86625-27D5-4DB5-B4D4-1A2CB804E56E | | Authorize API access
Supabase-48E0C7CB-DDDD-4305-B821-F3BEB52C4A4E | Authorize Cursor
Supabase-CE8F9905-FAE0-4C06-B77A-9F269B2100FE | | Authorize API access
Supabase-E37D2CD5-476F-4F49-A5FB-631B265025DC | Authorize Cursor
Supabase-DF078AEB-BB78-4647-9FA2-5D5403CCA5D6 | | Authorize API access
Supabase-D6F6817F-D8DD-4D55-85BB-A15100814AAB | Authorize Cursor
Supabase-E457B580-9786-43AD-9CF9-FE4F5BB8E785 | | Authorize API access
Supabase-4F3D6AA4-E2E3-4526-B391-49B6E0861911 | Authorize Cursor
Supabase-CA9FFCC9-4CA2-4718-AD49-B02D86C6EF6A | | Authorize API access
Supabase-E507B7A5-9AD0-4F17-8743-63A7B47D171A | Authorize Cursor
Supabase-9844BB27-2429-4BA6-BD36-1AB54099F44F | | Authorize API access
Supabase-27684173-9DBB-4F6E-9F7F-87EFD4E10A5F | Authorize Cursor
Supabase-04E31F7B-D098-4814-A394-01CE3D3E5A51 | | Authorize API access
Supabase-207CBC69-4957-499C-92E8-163F2B34C8AD | Authorize API Access
Supabase-C1627071-4AE2-4012-8F7C-4E6D883618A3 | ## To test A mock toolbar is included for easy local testing. Navigate to `/authorize?mock=loading` and then switch between the following variants: | State | What to check | | --- | --- | | `loading` | Shimmer skeleton inside the card | | `ready` | Regular waiting state | | `approving` | Authorize button shows spinner, both buttons disabled | | `approved` | Success admonition: "Authorization approved" | | `expired` | Warning admonition: "Authorization request expired", no action buttons | | `organizations-loading` | Org selector shimmer, no action buttons | | `organizations-error` | "Unable to load organizations" admonition, no action buttons | | `empty` | "No organizations found" admonition, no action buttons | | `not-member` | "Organization unavailable" admonition, no action buttons | | `error` | "Unable to load authorization" error screen | Then please test the `organization_slug` prefill: `/authorize?mock=ready&organization_slug=`. That org selector should be pre-selected and locked. To test against a real OAuth app, use a registered app on `supabase.green` — the mock states cover all edge cases but a live round-trip confirms the approve/decline API calls. ## Summary by CodeRabbit ## Release Notes * **New Features** * Added mock preview functionality for testing API authorization and Connect flows * Introduced collapsible, grouped permissions view for OAuth authorization requests * **Refactor** * Redesigned API authorization screens with improved layout and messaging * Restructured permissions display for better organization and clarity * **Bug Fixes** * Fixed inline link underline decoration color * **Tests** * Updated authorization flow test assertions to match new UI behavior [![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46359?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) --------- Co-authored-by: Claude Sonnet 4.6 Co-authored-by: Ali Waseem --- .../ApiAuthorization.Approved.tsx | 63 +-- .../ApiAuthorization.Error.tsx | 36 +- .../ApiAuthorization.Form.tsx | 379 +++++++-------- .../ApiAuthorization.Loading.tsx | 50 +- .../ApiAuthorization.Valid.tsx | 55 ++- .../ApiAuthorization/ApiAuthorization.tsx | 3 +- .../OAuthApps/AuthorizeRequesterDetails.tsx | 446 +++++++++++++----- .../components/layouts/InterstitialLayout.tsx | 77 +-- apps/studio/components/ui/InlineLink.tsx | 2 +- .../api-authorization-query.ts | 1 + apps/studio/pages/authorize.tsx | 23 +- .../components/ApiAuthorization.test.tsx | 76 ++- 12 files changed, 714 insertions(+), 497 deletions(-) diff --git a/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Approved.tsx b/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Approved.tsx index b2dd9fe93c5..6a3f0da6607 100644 --- a/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Approved.tsx +++ b/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Approved.tsx @@ -1,8 +1,12 @@ import dayjs from 'dayjs' import type { ReactNode } from 'react' -import { Alert, AlertDescription, AlertTitle, Card, CardContent, CardHeader, CheckIcon } from 'ui' +import { Admonition } from 'ui-patterns' -import { AuthorizeRequesterDetails } from '@/components/interfaces/Organization/OAuthApps/AuthorizeRequesterDetails' +import { + AuthorizeRequesterDetails, + RequesterLogo, +} from '@/components/interfaces/Organization/OAuthApps/AuthorizeRequesterDetails' +import { InterstitialLayout, LogoPair, SupabaseLogo } from '@/components/layouts/InterstitialLayout' import type { ApiAuthorizationResponse } from '@/data/api-authorization/api-authorization-query' import type { Organization } from '@/types' @@ -15,31 +19,36 @@ export function ApiAuthorizationApprovedScreen({ requester, organization, }: ApiAuthorizationApprovedScreenProps): ReactNode { + const organizationName = organization?.name ?? 'Unknown' + return ( - - Authorize API access for {requester.name} - - - - This authorization request has been approved - -

- {requester.name} has been approved access to the organization " - {organization?.name ?? 'Unknown'}" and all of its projects for the following scopes: -

- -

- Approved on: {dayjs(requester.approved_at).format('DD MMM YYYY HH:mm:ss (ZZ)')} -

-
-
-
-
+ } + right={} + /> + } + title={requester.name} + description="is authorized for Supabase" + > +
+ + +

+ Approved on {dayjs(requester.approved_at).format('DD MMM YYYY HH:mm:ss (ZZ)')}. +

+
+
) } diff --git a/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Error.tsx b/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Error.tsx index f52235cc76f..4a1f5cfe1c9 100644 --- a/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Error.tsx +++ b/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Error.tsx @@ -1,6 +1,9 @@ +import Link from 'next/link' import type { ReactNode } from 'react' -import { Alert, AlertDescription, AlertTitle, Card, CardContent, CardHeader, WarningIcon } from 'ui' +import { Button } from 'ui' +import { Admonition } from 'ui-patterns' +import { InterstitialLayout, SupabaseLogo } from '@/components/layouts/InterstitialLayout' import type { ResourceError } from '@/data/api-authorization/api-authorization-query' export interface ApiAuthorizationErrorScreenProps { @@ -11,18 +14,23 @@ export function ApiAuthorizationErrorScreen({ error, }: ApiAuthorizationErrorScreenProps): ReactNode { return ( - - Authorize API access - - - - Failed to fetch details for API authorization request - -

Please retry your authorization request from the requesting app

- {error &&

Error: {error?.message}

} -
-
-
-
+ } title="Unable to load authorization"> +
+ + Retry the authorization request from the requesting app. + {error && ( + Error: {error.message} + )} + + } + /> + +
+
) } diff --git a/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Form.tsx b/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Form.tsx index ddbff61db74..f22b2601c19 100644 --- a/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Form.tsx +++ b/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Form.tsx @@ -1,34 +1,28 @@ import dayjs from 'dayjs' -import Link from 'next/link' -import { useMemo, type ReactNode } from 'react' +import { type ReactNode } from 'react' import type { UseFormReturn } from 'react-hook-form' import { - Alert, - AlertDescription, - AlertTitle, Button, - Card, - CardContent, - CardFooter, - CardHeader, Form, FormControl, FormField, FormItem, + FormMessage, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, - WarningIcon, } from 'ui' -import { ShimmeringLoader } from 'ui-patterns' -import { FormLayout } from 'ui-patterns/form/Layout/FormLayout' +import { Admonition, ShimmeringLoader } from 'ui-patterns' import type { ApprovalState, IApprovalFormSchema } from './ApiAuthorization.Schema' -import { AuthorizeRequesterDetails } from '@/components/interfaces/Organization/OAuthApps/AuthorizeRequesterDetails' +import { + AuthorizeRequesterDetails, + RequesterLogo, +} from '@/components/interfaces/Organization/OAuthApps/AuthorizeRequesterDetails' +import { InterstitialLayout, LogoPair, SupabaseLogo } from '@/components/layouts/InterstitialLayout' import type { ApiAuthorizationResponse } from '@/data/api-authorization/api-authorization-query' -import { BASE_PATH } from '@/lib/constants' import type { Organization, ResponseError } from '@/types' type OrganizationsState_Loading = { @@ -53,13 +47,22 @@ type OrganizationsState_Success = { organizations: Array } -type OrganizationsState = +export type OrganizationsState = | OrganizationsState_Loading | OrganizationsState_Error | OrganizationsState_Empty | OrganizationsState_NotMember | OrganizationsState_Success +function isExternalRedirectUrl(url: string): boolean { + try { + const { hostname } = new URL(url) + return hostname !== 'localhost' && hostname !== '127.0.0.1' && hostname !== '::1' + } catch { + return false + } +} + export interface ApiAuthorizationMainViewProps { approvalState: ApprovalState form: UseFormReturn @@ -79,89 +82,87 @@ export function ApiAuthorizationMainView({ onApprove, onDecline, }: ApiAuthorizationMainViewProps): ReactNode { - const isMcpClient = requester.registration_type === 'dynamic' const isExpired = dayjs().isAfter(dayjs(requester.expires_at)) + const showReadyContent = !isExpired && organizations._tag === 'success' + const redirectUrl = requester.redirect_uri ?? requester.website + const externalRedirectUrl = isExternalRedirectUrl(redirectUrl) ? redirectUrl : undefined return ( - - {isMcpClient && } - - {isExpired && } - {organizations._tag === 'loading' && } - {organizations._tag === 'error' && } - {organizations._tag === 'empty' && } - {organizations._tag === 'not_member' && } - {organizations._tag === 'success' && ( - } + right={} /> - )} - - - ) -} - -interface FormShellProps { - title: string - children: ReactNode -} - -function FormShell({ title, children }: FormShellProps): ReactNode { - return ( - - {title} - {children} - - ) -} - -function McpNotice(): ReactNode { - return ( - - - MCP Client Connection - - This is an MCP (Model Context Protocol) client designed to connect with AI applications. - Please ensure you trust this application before granting access to your organization's data. - - + } + title={`Authorize ${requester.name}`} + description="This application wants to access your Supabase account" + > +
+ Authorize API access for {requester.name} +
+ {isExpired ? ( + + ) : ( + <> + {organizations._tag === 'loading' && } + {organizations._tag === 'error' && ( + + )} + {organizations._tag === 'empty' && } + {organizations._tag === 'not_member' && } + {organizations._tag === 'success' && ( + + )} + {showReadyContent && ( + <> + + + + )} + + )} +
+
+ ) } function ExpiredNotice(): ReactNode { return ( - - - This authorization request is expired - - Please retry your authorization request from the requesting app - - + ) } function OrganizationsLoader(): ReactNode { return ( -
- - -
+
+

+ Organization +

+ +
) } @@ -171,40 +172,38 @@ interface OrganizationsErrorNoticeProps { function OrganizationsErrorNotice({ error }: OrganizationsErrorNoticeProps): ReactNode { return ( - - - There was an error loading your organizations - - Please try again. If the problem persists, contact support. - {error &&

Error: {error.message}

} -
-
+ + Please try again. If the problem persists, contact support. + {error && ( + Error: {error.message} + )} + + } + /> ) } function OrganizationsEmptyState(): ReactNode { return ( - - - Organization is needed for installing an integration - - Your account isn't associated with any organizations. To use this integration, it must be - installed within an organization. You'll be redirected to create an organization first. - - + ) } function NotMemberOfOrganizationNotice(): ReactNode { return ( - - - Organization is needed for installing an integration - - Your account is not a member of the pre-selected organization. To use this integration, it - must be installed within an organization your account is associated with. - - + ) } @@ -228,40 +227,47 @@ function OrganizationSelector({ ( - - - - { + field.onChange(value) + form.trigger('selectedOrgSlug') + }} + > + - - - - - {organizations.map((organization) => ( - - {organization.name} - - ))} - - - - + + + + {organizations.map((organization) => ( + + {organization.name} + + ))} + + + + )} /> @@ -270,87 +276,45 @@ function OrganizationSelector({ } interface FormFooterProps { - disabled?: boolean approvalState: ApprovalState requester: ApiAuthorizationResponse - organizations: OrganizationsState + redirectUrl?: string onDecline: () => void onApprove: () => void } function FormFooter({ - disabled = false, approvalState, requester, - organizations, + redirectUrl, onDecline, onApprove, }: FormFooterProps): ReactNode { - const showApprovalButton = organizations._tag === 'success' || organizations._tag === 'not_member' - return ( - +
+ - {organizations._tag === 'loading' && ( - Authorize {requester.name} + {redirectUrl && ( +
+

+ Authorizing will redirect you to {redirectUrl} +

+
)} - {organizations._tag === 'empty' && } - {showApprovalButton && ( - - )} - - ) -} - -interface LoadingApprovalButtonProps { - children: ReactNode -} - -function LoadingApprovalButton({ children }: LoadingApprovalButtonProps): ReactNode { - return -} - -function createReturnToSearchParam(): string | null { - if (typeof window === 'undefined') { - return null - } - - const basePath = BASE_PATH - - let pathname = basePath ? location.pathname.replace(basePath, '') : location.pathname - if (location.search) { - pathname += location.search - } - - return pathname -} - -function CreateOrganizationLink(): ReactNode { - const searchParamString = useMemo(function createSearchParams() { - const searchParams = new URLSearchParams() - const returnTo = createReturnToSearchParam() - if (returnTo) { - searchParams.set('returnTo', returnTo) - } - return searchParams.toString() - }, []) - - return ( - +
) } @@ -368,7 +332,14 @@ function ApprovalButton({ onApprove, }: ApprovalButtonProps): ReactNode { return ( - ) diff --git a/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Loading.tsx b/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Loading.tsx index 89e6c6ff0a2..a28e51b7e20 100644 --- a/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Loading.tsx +++ b/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Loading.tsx @@ -1,28 +1,40 @@ import type { ReactNode } from 'react' -import { Card, CardContent, CardHeader } from 'ui' +import { Card, CardContent } from 'ui' import { ShimmeringLoader } from 'ui-patterns' +import { InterstitialLayout, SupabaseLogo } from '@/components/layouts/InterstitialLayout' + export function ApiAuthorizationLoadingScreen(): ReactNode { return ( - - Authorize API access - + } + title={} + description={} + > +
Loading... -
- - +
+ + + +
+ + +
+
+
+ + + + + + +
+ + +
- -
- - -
- -
- - -
- - +
+ ) } diff --git a/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Valid.tsx b/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Valid.tsx index 8f6ebdf5517..cb85776418a 100644 --- a/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Valid.tsx +++ b/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.Valid.tsx @@ -1,4 +1,5 @@ import { zodResolver } from '@hookform/resolvers/zod' +import Head from 'next/head' import { useEffect, useEffectEvent, useMemo, useState, type ReactNode } from 'react' import { useForm, type UseFormReturn } from 'react-hook-form' import { toast } from 'sonner' @@ -16,6 +17,7 @@ import { useApiAuthorizationApproveMutation } from '@/data/api-authorization/api import { useApiAuthorizationDeclineMutation } from '@/data/api-authorization/api-authorization-decline-mutation' import { useApiAuthorizationQuery } from '@/data/api-authorization/api-authorization-query' import { useOrganizationsQuery } from '@/data/organizations/organizations-query' +import { buildStudioPageTitle } from '@/lib/page-title' import type { Organization } from '@/types' function getMatchingOrganization( @@ -45,16 +47,19 @@ function preselectOrganizationSlug({ } } -function useOrganizationsState(organization_slug: string | undefined) { +function useOrganizationsState(organization_slug: string | undefined, enabled = true) { const { data: organizations, isPending: isLoadingOrganizations, isError: isErrorOrganizations, error: organizationsError, - } = useOrganizationsQuery() + } = useOrganizationsQuery({ enabled }) const organizationsState = useMemo( function calculateOrganizationsState() { + if (!enabled) { + return { _tag: 'loading' as const } + } if (isLoadingOrganizations) { return { _tag: 'loading' as const } } @@ -73,6 +78,7 @@ function useOrganizationsState(organization_slug: string | undefined) { return { _tag: 'success' as const, organizations } }, [ + enabled, isLoadingOrganizations, isErrorOrganizations, organizationsError, @@ -179,28 +185,47 @@ export function ApiAuthorizationValidScreen({ return } + const effectiveRequester = requester + const effectiveOrganizationsState = organizationsState + const effectiveOrganizationSlug = organization_slug + const effectiveApprovalState = approvalState + const pageTitle = effectiveRequester + ? buildStudioPageTitle({ section: `Authorize ${effectiveRequester.name}`, brand: 'Supabase' }) + : undefined + + if (!effectiveRequester) return null + if (isApproved) { const approvedOrganization = - organizationsState._tag === 'success' - ? organizationsState.organizations.find( - (org) => org.slug === requester.approved_organization_slug + effectiveOrganizationsState._tag === 'success' + ? effectiveOrganizationsState.organizations.find( + (org) => org.slug === effectiveRequester.approved_organization_slug ) : undefined return ( - + <> + {pageTitle && {pageTitle}} + + ) } return ( - + <> + {pageTitle && {pageTitle}} + + ) } diff --git a/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.tsx b/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.tsx index 43ff848e09d..7e710d72e68 100644 --- a/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.tsx +++ b/apps/studio/components/interfaces/ApiAuthorization/ApiAuthorization.tsx @@ -12,8 +12,7 @@ export function ApiAuthorizationScreen({ organization_slug, navigate, }: ApiAuthorizationScreenProps) { - const valid = !!auth_id - if (!valid) { + if (!auth_id) { return } diff --git a/apps/studio/components/interfaces/Organization/OAuthApps/AuthorizeRequesterDetails.tsx b/apps/studio/components/interfaces/Organization/OAuthApps/AuthorizeRequesterDetails.tsx index dc8aca5c40c..9d5aad764c8 100644 --- a/apps/studio/components/interfaces/Organization/OAuthApps/AuthorizeRequesterDetails.tsx +++ b/apps/studio/components/interfaces/Organization/OAuthApps/AuthorizeRequesterDetails.tsx @@ -1,7 +1,25 @@ import { OAuthScope } from '@supabase/shared-types/out/constants' -import { Check } from 'lucide-react' +import { Check, ChevronDown } from 'lucide-react' +import { useMemo, useState } from 'react' +import { + Badge, + Card, + CardContent, + cn, + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from 'ui' +import { InfoTooltip } from 'ui-patterns/info-tooltip' import { PERMISSIONS_DESCRIPTIONS } from './OAuthApps.constants' +import { LogoBox } from '@/components/layouts/InterstitialLayout' +import { InlineLink } from '@/components/ui/InlineLink' +import { DOCS_URL } from '@/lib/constants' + +const OAUTH_SCOPES_DOCS_URL = `${DOCS_URL}/guides/platform/oauth-apps/oauth-scopes` +const PERMISSION_DETAILS_TRIGGER_CLASSNAME = + 'mx-auto flex h-7 cursor-pointer items-center justify-center gap-1.5 rounded-md px-2 text-xs text-foreground-lighter transition-colors hover:bg-surface-200 hover:text-foreground' export interface AuthorizeRequesterDetailsProps { icon: string | null @@ -20,141 +38,307 @@ export const ScopeSection = ({ hasReadScope: boolean hasWriteScope: boolean }) => { - if (hasReadScope || hasWriteScope) { - const perms = [hasReadScope ? 'Read' : null, hasWriteScope ? 'Write' : null] - .filter(Boolean) + if (!hasReadScope && !hasWriteScope) return null - .map((str) => ( - - {str} - - )) - .reduce((acc, v) => ( - <> - {acc} - and - {v} - - )) + const permissions = [hasReadScope ? 'Read' : null, hasWriteScope ? 'Write' : null] + .filter(Boolean) + .join(' and ') - return ( -
-
- -
-
- {perms} {description} -
-
- ) - } - return null -} - -export const AuthorizeRequesterDetails = ({ - icon, - name, - domain, - scopes, - showOnlyScopes = false, -}: AuthorizeRequesterDetailsProps) => { return ( -
- {!showOnlyScopes && ( -
-
-
- {!icon &&

{name[0]}

} -
-
-

- {name} ({domain}) is requesting API access to an organization. -

-
- )} +
+
+ +
- {!showOnlyScopes && ( - <> -

Permissions

-

- The following scopes will apply for the{' '} - selected organization and all of its projects. -

- - )} -
- {scopes.length === 0 && ( -

- No permissions requested, {name} will not have access to your organization or projects -

- )} - - - - - - - - - - - - -
+ {permissions} {description}
) } + +type PermissionLevel = 'read' | 'write' | 'read-write' + +type PermissionItem = { + label: string + description: string + read?: OAuthScope + write?: OAuthScope +} + +type PermissionGroup = { + label: string + items: PermissionItem[] +} + +const PERMISSION_GROUPS: PermissionGroup[] = [ + { + label: 'Data & authentication', + items: [ + { + label: 'Database', + description: PERMISSIONS_DESCRIPTIONS.DATABASE, + read: OAuthScope.DATABASE_READ, + write: OAuthScope.DATABASE_WRITE, + }, + { + label: 'Secrets', + description: PERMISSIONS_DESCRIPTIONS.SECRETS, + read: OAuthScope.SECRETS_READ, + write: OAuthScope.SECRETS_WRITE, + }, + { + label: 'Auth', + description: PERMISSIONS_DESCRIPTIONS.AUTH, + read: OAuthScope.AUTH_READ, + write: OAuthScope.AUTH_WRITE, + }, + ], + }, + { + label: 'Code execution', + items: [ + { + label: 'Edge Functions', + description: PERMISSIONS_DESCRIPTIONS.EDGE_FUNCTIONS, + read: OAuthScope.EDGE_FUNCTIONS_READ, + write: OAuthScope.EDGE_FUNCTIONS_WRITE, + }, + ], + }, + { + label: 'Platform management', + items: [ + { + label: 'Environment', + description: PERMISSIONS_DESCRIPTIONS.ENVIRONMENT, + read: OAuthScope.ENVIRONMENT_READ, + write: OAuthScope.ENVIRONMENT_WRITE, + }, + { + label: 'Organizations', + description: PERMISSIONS_DESCRIPTIONS.ORGANIZATIONS, + read: OAuthScope.ORGANIZATIONS_READ, + write: OAuthScope.ORGANIZATIONS_WRITE, + }, + { + label: 'Projects', + description: PERMISSIONS_DESCRIPTIONS.PROJECTS, + read: OAuthScope.PROJECTS_READ, + write: OAuthScope.PROJECTS_WRITE, + }, + { + label: 'Domains', + description: PERMISSIONS_DESCRIPTIONS.DOMAINS, + read: OAuthScope.DOMAINS_READ, + write: OAuthScope.DOMAINS_WRITE, + }, + { + label: 'PostgREST', + description: PERMISSIONS_DESCRIPTIONS.REST, + read: OAuthScope.REST_READ, + write: OAuthScope.REST_WRITE, + }, + ], + }, + { + label: 'Files & monitoring', + items: [ + { + label: 'Analytics', + description: PERMISSIONS_DESCRIPTIONS.ANALYTICS, + read: OAuthScope.ANALYTICS_READ, + write: OAuthScope.ANALYTICS_WRITE, + }, + { + label: 'Analytics configuration', + description: PERMISSIONS_DESCRIPTIONS.ANALYTICS_CONFIG, + read: OAuthScope.ANALYTICS_CONFIG_READ, + write: OAuthScope.ANALYTICS_CONFIG_WRITE, + }, + { + label: 'Storage', + description: PERMISSIONS_DESCRIPTIONS.STORAGE, + read: OAuthScope.STORAGE_READ, + write: OAuthScope.STORAGE_WRITE, + }, + ], + }, +] + +export const RequesterLogo = ({ icon, name }: { icon: string | null; name: string }) => ( + + {icon ? ( + {name} + ) : ( + {name.slice(0, 1)} + )} + +) + +export const AuthorizeRequesterDetails = ({ + name, + scopes, + showOnlyScopes = false, +}: AuthorizeRequesterDetailsProps) => { + const [showDetails, setShowDetails] = useState(showOnlyScopes) + const requestedPermissions = useMemo(() => getRequestedPermissions(scopes), [scopes]) + const writablePermissions = requestedPermissions.filter(({ level }) => level !== 'read') + const readOnlyPermissions = requestedPermissions.filter(({ level }) => level === 'read') + + return ( +
+ {requestedPermissions.length === 0 ? ( + + + No permissions requested. + + + ) : ( + <> + {!showOnlyScopes && ( + <> +
+

+ Permissions +

+

+ Authorizing {name} grants it the following{' '} + access permissions to the + selected organization. Only continue if you trust this app. +

+
+ + + +
+ {writablePermissions.length > 0 && ( + + )} + {readOnlyPermissions.length > 0 && ( + + )} +
+
+
+ + )} + + + + {showDetails ? 'Hide detailed permissions' : 'Show detailed permissions'} + + + + + + + + )} +
+ ) +} + +function PermissionSummaryRow({ + permissions, + level, +}: { + permissions: Array + level: PermissionLevel +}) { + return ( +
+

+ {permissions.map(({ label }) => label).join(', ')} +

+ + {formatPermissionLevel(level)} + +
+ ) +} + +function PermissionDetails({ + requestedPermissions, +}: { + requestedPermissions: Array +}) { + const requestedByLabel = new Map( + requestedPermissions.map((permission) => [permission.label, permission]) + ) + + return ( + + + {PERMISSION_GROUPS.map((group) => { + const groupPermissions = group.items + .map((item) => requestedByLabel.get(item.label)) + .filter(Boolean) as RequestedPermission[] + + if (groupPermissions.length === 0) return null + + return ( +
+

+ {group.label} +

+
+ {groupPermissions.map((permission) => ( +
+
+

{permission.label}

+ + {formatPermissionDescription(permission.description)} + +
+ + {formatPermissionLevel(permission.level)} + +
+ ))} +
+
+ ) + })} +
+
+ ) +} + +type RequestedPermission = PermissionItem & { + level: PermissionLevel +} + +function getRequestedPermissions(scopes: OAuthScope[]): RequestedPermission[] { + return PERMISSION_GROUPS.flatMap((group) => + group.items.flatMap((item) => { + const hasReadScope = !!item.read && scopes.includes(item.read) + const hasWriteScope = !!item.write && scopes.includes(item.write) + + if (!hasReadScope && !hasWriteScope) return [] + + return { + ...item, + level: hasReadScope && hasWriteScope ? 'read-write' : hasWriteScope ? 'write' : 'read', + } + }) + ) +} + +function formatPermissionLevel(level: PermissionLevel) { + if (level === 'read') return 'Read' + if (level === 'write') return 'Write' + return 'Read + Write' +} + +function formatPermissionDescription(description: string) { + return description.charAt(0).toUpperCase() + description.slice(1) +} + +function getPermissionLevelBadgeVariant(level: PermissionLevel) { + return level === 'read' ? 'default' : 'warning' +} diff --git a/apps/studio/components/layouts/InterstitialLayout.tsx b/apps/studio/components/layouts/InterstitialLayout.tsx index 7259e6ca7d3..486e2246c21 100644 --- a/apps/studio/components/layouts/InterstitialLayout.tsx +++ b/apps/studio/components/layouts/InterstitialLayout.tsx @@ -18,6 +18,13 @@ interface InterstitialLayoutProps { descriptionClassName?: string } +/** + * Minimal full-screen centered layout for interstitial flows: + * partner authorization, org invites, CLI auth, credit redemption, etc. + * + * The logo, title, and description render inside the card (above children), + * so every consumer gets a consistent header for free. + */ export const InterstitialLayout = ({ logo, title, @@ -31,6 +38,28 @@ export const InterstitialLayout = ({ const TitleElement = typeof title === 'string' ? 'h1' : 'div' const DescriptionElement = typeof description === 'string' ? 'p' : 'div' + const titleElement = title ? ( + + {title} + + ) : null + + const descriptionElement = description ? ( + + {description} + + ) : null + return (
{(logo || title || description) && ( - + {logo &&
{logo}
} - {(title || description) && ( + {(titleElement || descriptionElement) && (
- {title && ( - - {title} - - )} - {description && ( - - {description} - - )} + {titleElement} + {descriptionElement}
)}
@@ -78,6 +89,11 @@ export const InterstitialLayout = ({ ) } +/** + * Standard rounded-rect logo container (48x48). + * Partner logos fill edge-to-edge (see `PartnerLogo`); the Supabase symbol and + * Lucide icons sit inset (sized at `size-7`). + */ export const LogoBox = ({ children, className }: { children: ReactNode; className?: string }) => (
) +/** Two pre-boxed logos side-by-side with a swap separator. */ export const LogoPair = ({ left, right }: { left: ReactNode; right: ReactNode }) => (
{left} @@ -97,18 +114,20 @@ export const LogoPair = ({ left, right }: { left: ReactNode; right: ReactNode })
) -export const SupabaseLogo = () => ( - - Supabase - -) - +/** Partner logo rendered edge-to-edge inside a LogoBox. */ export const PartnerLogo = ({ src, alt }: { src: string; alt: string }) => ( {alt} ) +/** Supabase symbol (not the wordmark) rendered inset inside a LogoBox. */ +export const SupabaseLogo = () => ( + + Supabase + +) + export const InterstitialAccountRow = ({ avatarUrl, displayName, diff --git a/apps/studio/components/ui/InlineLink.tsx b/apps/studio/components/ui/InlineLink.tsx index bdd788a16f9..69a3693f1e6 100644 --- a/apps/studio/components/ui/InlineLink.tsx +++ b/apps/studio/components/ui/InlineLink.tsx @@ -12,7 +12,7 @@ interface InlineLinkProps { } export const InlineLinkClassName = - 'underline transition underline-offset-2 decoration-foreground-lighter hover:decoration-foreground text-inherit hover:text-foreground' + 'underline transition underline-offset-2 decoration-inherit hover:decoration-foreground text-inherit hover:text-foreground' export const InlineLink = ({ href, diff --git a/apps/studio/data/api-authorization/api-authorization-query.ts b/apps/studio/data/api-authorization/api-authorization-query.ts index f9cc58cfd63..9faf70396c2 100644 --- a/apps/studio/data/api-authorization/api-authorization-query.ts +++ b/apps/studio/data/api-authorization/api-authorization-query.ts @@ -14,6 +14,7 @@ export type ApiAuthorizationResponse = { website: string icon: string | null domain: string + redirect_uri?: string scopes: OAuthScope[] expires_at: string approved_at: string | null diff --git a/apps/studio/pages/authorize.tsx b/apps/studio/pages/authorize.tsx index 4d9a6be479a..4dc816778d9 100644 --- a/apps/studio/pages/authorize.tsx +++ b/apps/studio/pages/authorize.tsx @@ -3,10 +3,12 @@ import Head from 'next/head' import { useRouter } from 'next/router' import { ApiAuthorizationScreen } from '@/components/interfaces/ApiAuthorization/ApiAuthorization' -import { APIAuthorizationLayout } from '@/components/layouts/APIAuthorizationLayout' import { withAuth } from '@/hooks/misc/withAuth' +import { buildStudioPageTitle } from '@/lib/page-title' import type { NextPageWithLayout } from '@/types' +const PAGE_TITLE = buildStudioPageTitle({ section: 'Authorize API Access', brand: 'Supabase' }) + const APIAuthorizationPage: NextPageWithLayout = () => { const router = useRouter() const routerReady = router.isReady @@ -17,16 +19,17 @@ const APIAuthorizationPage: NextPageWithLayout = () => { } return ( - router.push(destination)} - /> + <> + + {PAGE_TITLE} + + router.push(destination)} + /> + ) } -APIAuthorizationPage.getLayout = (page) => ( - {page} -) - export default withAuth(APIAuthorizationPage) diff --git a/apps/studio/tests/components/ApiAuthorization.test.tsx b/apps/studio/tests/components/ApiAuthorization.test.tsx index d1d6bfd5282..2ac4757a4f9 100644 --- a/apps/studio/tests/components/ApiAuthorization.test.tsx +++ b/apps/studio/tests/components/ApiAuthorization.test.tsx @@ -150,7 +150,7 @@ describe('ApiAuthorizationScreen', () => { response: () => HttpResponse.json({ message: 'Not found' }, { status: 404 }), }) renderScreen() - await screen.findByText('Failed to fetch details for API authorization request') + await screen.findByText('Unable to load authorization') }) describe('when already approved', () => { @@ -162,8 +162,8 @@ describe('ApiAuthorizationScreen', () => { }) ) renderScreen() - await screen.findByText('This authorization request has been approved') - expect(screen.getByText(/organization "My Org"/)).toBeInTheDocument() + await screen.findByText('Authorization approved') + expect(screen.getByText(/has access to My Org/)).toBeInTheDocument() }) test('shows Unknown when approved organization is not in the user organizations list', async () => { @@ -174,14 +174,14 @@ describe('ApiAuthorizationScreen', () => { }) ) renderScreen() - await screen.findByText('This authorization request has been approved') - expect(screen.getByText(/organization "Unknown"/)).toBeInTheDocument() + await screen.findByText('Authorization approved') + expect(screen.getByText(/has access to Unknown/)).toBeInTheDocument() }) }) describe('main authorization form', () => { describe('organizations states', () => { - test('disables action buttons while organizations are being fetched', async () => { + test('does not show action buttons while organizations are being fetched', async () => { mockAuthEndpoint(createMockAuthResponse()) addAPIMock({ method: 'get', @@ -190,11 +190,13 @@ describe('ApiAuthorizationScreen', () => { }) renderScreen() await screen.findByText('Authorize API access for Test App') - expect(screen.getByRole('button', { name: 'Decline' })).toBeDisabled() - expect(screen.getByRole('button', { name: /Authorize Test App/ })).toBeDisabled() + expect(screen.queryByRole('button', { name: 'Cancel' })).not.toBeInTheDocument() + expect( + screen.queryByRole('button', { name: /Authorize Test App/ }) + ).not.toBeInTheDocument() }) - test('shows error notice, disables decline button, and hides accept button when organizations query fails', async () => { + test('shows error notice and hides action buttons when organizations query fails', async () => { mockAuthEndpoint(createMockAuthResponse()) addAPIMock({ method: 'get', @@ -203,8 +205,8 @@ describe('ApiAuthorizationScreen', () => { HttpResponse.json({ message: 'Server error' }, { status: 500 }), }) renderScreen() - await screen.findByText('There was an error loading your organizations') - expect(screen.getByRole('button', { name: 'Decline' })).toBeDisabled() + await screen.findByText('Unable to load organizations') + expect(screen.queryByRole('button', { name: 'Cancel' })).not.toBeInTheDocument() expect( screen.queryByRole('button', { name: /Authorize Test App/ }) ).not.toBeInTheDocument() @@ -213,9 +215,8 @@ describe('ApiAuthorizationScreen', () => { test('shows empty state when user has no organizations', async () => { mockBothEndpoints(createMockAuthResponse(), []) renderScreen() - await screen.findByText(/Your account isn't associated with any organizations/) - expect(screen.getByRole('link', { name: 'Create an organization' })).toBeInTheDocument() - expect(screen.getByRole('button', { name: 'Decline' })).toBeDisabled() + await screen.findByText('No organizations found') + expect(screen.queryByRole('button', { name: 'Cancel' })).not.toBeInTheDocument() expect( screen.queryByRole('button', { name: /Authorize Test App/ }) ).not.toBeInTheDocument() @@ -225,8 +226,10 @@ describe('ApiAuthorizationScreen', () => { mockBothEndpoints() renderScreen({ organization_slug: 'nonexistent-org' }) await screen.findByText(/Your account is not a member of the pre-selected organization/) - expect(screen.getByRole('button', { name: 'Decline' })).toBeDisabled() - expect(screen.getByRole('button', { name: /Authorize Test App/ })).toBeDisabled() + expect(screen.queryByRole('button', { name: 'Cancel' })).not.toBeInTheDocument() + expect( + screen.queryByRole('button', { name: /Authorize Test App/ }) + ).not.toBeInTheDocument() }) }) @@ -237,7 +240,7 @@ describe('ApiAuthorizationScreen', () => { await screen.findByText('Authorize API access for My OAuth App') expect(screen.getByRole('combobox')).toBeInTheDocument() expect(screen.getByRole('button', { name: /Authorize My OAuth App/ })).toBeInTheDocument() - expect(screen.getByRole('button', { name: 'Decline' })).toBeInTheDocument() + expect(screen.getByRole('button', { name: 'Cancel' })).toBeInTheDocument() }) test('auto-selects the only organization when no organization_slug is provided', async () => { @@ -253,45 +256,28 @@ describe('ApiAuthorizationScreen', () => { const combobox = await screen.findByRole('combobox') expect(combobox).toHaveTextContent('Second Org') expect(combobox).not.toHaveTextContent('My Org') - expect( - screen.getByText('This organization has been pre-selected by Test App.') - ).toBeInTheDocument() - }) - }) - - describe('MCP client warning', () => { - test('shows MCP warning when registration_type is dynamic', async () => { - mockBothEndpoints(createMockAuthResponse({ registration_type: 'dynamic' })) - renderScreen() - await screen.findByText('MCP Client Connection') - }) - - test('does not show MCP warning for non-dynamic registration type', async () => { - mockBothEndpoints() - renderScreen() - await screen.findByText('Authorize API access for Test App') - expect(screen.queryByText('MCP Client Connection')).not.toBeInTheDocument() + expect(screen.getByText('Pre-selected by Test App')).toBeInTheDocument() }) }) describe('expiration', () => { - test('shows expiration warning and disables buttons when request has expired', async () => { + test('shows expiration warning and hides action buttons when request has expired', async () => { mockBothEndpoints( createMockAuthResponse({ expires_at: dayjs().subtract(1, 'hour').toISOString() }) ) renderScreen() - await screen.findByText('This authorization request is expired') - expect(screen.getByRole('button', { name: 'Decline' })).toBeDisabled() - expect(screen.getByRole('button', { name: /Authorize Test App/ })).toBeDisabled() + await screen.findByText('Authorization request expired') + expect(screen.queryByRole('button', { name: 'Cancel' })).not.toBeInTheDocument() + expect( + screen.queryByRole('button', { name: /Authorize Test App/ }) + ).not.toBeInTheDocument() }) test('does not show expiration warning when request has not expired', async () => { mockBothEndpoints() renderScreen() await screen.findByText('Authorize API access for Test App') - expect( - screen.queryByText('This authorization request is expired') - ).not.toBeInTheDocument() + expect(screen.queryByText('Authorization request expired')).not.toBeInTheDocument() }) }) @@ -317,7 +303,7 @@ describe('ApiAuthorizationScreen', () => { }) describe('decline action', () => { - test('navigates to /organizations after declining', async () => { + test('navigates to /organizations after cancelling', async () => { const user = userEvent.setup() const declineHandler = vi.fn(() => HttpResponse.json({ id: 'test-auth-id' }) @@ -329,8 +315,8 @@ describe('ApiAuthorizationScreen', () => { response: declineHandler, }) const { navigate } = renderScreen() - await screen.findByRole('button', { name: 'Decline' }) - await user.click(screen.getByRole('button', { name: 'Decline' })) + await screen.findByRole('button', { name: 'Cancel' }) + await user.click(screen.getByRole('button', { name: 'Cancel' })) await waitFor(() => expect(declineHandler).toHaveBeenCalled()) await waitFor(() => expect(navigate).toHaveBeenCalledWith('/organizations')) }) From 4af431da00fcd502bdbd733d578363fa63e1fc58 Mon Sep 17 00:00:00 2001 From: Katerina Skroumpelou Date: Mon, 8 Jun 2026 20:05:28 +0300 Subject: [PATCH 037/134] fix(docs): surface SDK diffs in js-libs-update workflow PRs (#46742) Two-part fix for the Update JS Client Libraries Docs workflow. First, the `make` invocation was narrowed to `make download.tsdoc.v2` so the workflow no longer re-downloads unrelated Management and Storage REST openapi specs alongside the JS TypeDoc files, which was the source of the noise in #46738. Second, the `build-reference-content` snapshot test now serializes to a JSON file via `toMatchFileSnapshot` with a cycle-breaker, because the previous `toMatchSnapshot` of a raw object was being collapsed to `[Object]` placeholders by pretty-format (533 of them), hiding every param rename, JSDoc edit, return-type change, and signature tweak. Verified against supabase-js v2.108.0: the `count` to `rows` rename in `PostgrestTransformBuilder.{limit,maxAffected}` now shows up in the snapshot diff as expected. ## Summary by CodeRabbit * **Chores** * Updated documentation generation workflow to run a more targeted build command. * Added ignore rule for test snapshot files and refreshed the autogenerated PR description/reference snapshot. * **Tests** * Improved test snapshot strategy to use file-based snapshots and robust handling of circular structures for more reliable assertions. --- .github/workflows/docs-js-libs-update.yml | 4 +- .prettierignore | 2 + .../build-reference-content.test.ts.snap | 27316 ----- .../build-reference-content.v2.json | 98066 ++++++++++++++++ .../scripts/build-reference-content.test.ts | 16 +- 5 files changed, 98085 insertions(+), 27319 deletions(-) delete mode 100644 apps/docs/scripts/__snapshots__/build-reference-content.test.ts.snap create mode 100644 apps/docs/scripts/__snapshots__/build-reference-content.v2.json diff --git a/.github/workflows/docs-js-libs-update.yml b/.github/workflows/docs-js-libs-update.yml index 68eeb3434bb..c2f5b64be5c 100644 --- a/.github/workflows/docs-js-libs-update.yml +++ b/.github/workflows/docs-js-libs-update.yml @@ -50,7 +50,7 @@ jobs: echo "Regenerating tsdoc files for JS client libraries..." echo "Source: ${SOURCE}" echo "Version: ${VERSION}" - make + make download.tsdoc.v2 - name: Refresh reference-content snapshot working-directory: apps/docs @@ -74,7 +74,7 @@ jobs: title: 'docs: update js sdk docs (${{ github.event.inputs.version }})' body: | Updates JS sdk documentation following stable release. - Ran `make` in apps/docs/spec to regenerate tsdoc files. + Ran `make download.tsdoc.v2` in apps/docs/spec and refreshed the reference-content snapshot. **Details:** - **Version:** `${{ github.event.inputs.version }}` diff --git a/.prettierignore b/.prettierignore index 46c5219234d..8c41d148ff5 100644 --- a/.prettierignore +++ b/.prettierignore @@ -31,3 +31,5 @@ apps/**/.contentlayer packages/ui/src/components/Form/examples/PhoneProvidersSchema.json # ignore because of

apps/www/_blog/2025-07-14-supabase-ui-platform-kit.mdx +# vitest file snapshots — JSON.stringify owns the format, not Prettier +apps/docs/scripts/__snapshots__/ diff --git a/apps/docs/scripts/__snapshots__/build-reference-content.test.ts.snap b/apps/docs/scripts/__snapshots__/build-reference-content.test.ts.snap deleted file mode 100644 index 6e8a295b385..00000000000 --- a/apps/docs/scripts/__snapshots__/build-reference-content.test.ts.snap +++ /dev/null @@ -1,27316 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`build-reference-content — javascript/v2 > matches snapshot 1`] = ` -{ - "bySlug": { - "analytics-buckets": { - "id": "analytics-buckets", - "slug": "analytics-buckets", - "title": "Analytics Buckets", - "type": "function", - }, - "analytics-buckets-createbucket": { - "id": "analytics-buckets-createbucket", - "product": "storage", - "slug": "analytics-buckets-createbucket", - "title": "createBucket", - "type": "function", - }, - "analytics-buckets-deletebucket": { - "id": "analytics-buckets-deletebucket", - "product": "storage", - "slug": "analytics-buckets-deletebucket", - "title": "deleteBucket", - "type": "function", - }, - "analytics-buckets-from": { - "id": "analytics-buckets-from", - "product": "storage", - "slug": "analytics-buckets-from", - "title": "from", - "type": "function", - }, - "analytics-buckets-listbuckets": { - "id": "analytics-buckets-listbuckets", - "product": "storage", - "slug": "analytics-buckets-listbuckets", - "title": "listBuckets", - "type": "function", - }, - "auth": { - "id": "auth", - "slug": "auth", - "title": "Overview", - "type": "function", - }, - "auth-admin": { - "id": "auth-admin", - "slug": "auth-admin", - "title": "Overview", - "type": "function", - }, - "auth-admin-createprovider": { - "id": "auth-admin-createprovider", - "product": "auth", - "slug": "auth-admin-createprovider", - "title": "createProvider", - "type": "function", - }, - "auth-admin-createuser": { - "id": "auth-admin-createuser", - "product": "auth", - "slug": "auth-admin-createuser", - "title": "createUser", - "type": "function", - }, - "auth-admin-deletefactor": { - "id": "auth-admin-deletefactor", - "product": "auth", - "slug": "auth-admin-deletefactor", - "title": "deleteFactor", - "type": "function", - }, - "auth-admin-deleteprovider": { - "id": "auth-admin-deleteprovider", - "product": "auth", - "slug": "auth-admin-deleteprovider", - "title": "deleteProvider", - "type": "function", - }, - "auth-admin-deleteuser": { - "id": "auth-admin-deleteuser", - "product": "auth", - "slug": "auth-admin-deleteuser", - "title": "deleteUser", - "type": "function", - }, - "auth-admin-generatelink": { - "id": "auth-admin-generatelink", - "product": "auth", - "slug": "auth-admin-generatelink", - "title": "generateLink", - "type": "function", - }, - "auth-admin-getprovider": { - "id": "auth-admin-getprovider", - "product": "auth", - "slug": "auth-admin-getprovider", - "title": "getProvider", - "type": "function", - }, - "auth-admin-getuserbyid": { - "id": "auth-admin-getuserbyid", - "product": "auth", - "slug": "auth-admin-getuserbyid", - "title": "getUserById", - "type": "function", - }, - "auth-admin-inviteuserbyemail": { - "id": "auth-admin-inviteuserbyemail", - "product": "auth", - "slug": "auth-admin-inviteuserbyemail", - "title": "inviteUserByEmail", - "type": "function", - }, - "auth-admin-listfactors": { - "id": "auth-admin-listfactors", - "product": "auth", - "slug": "auth-admin-listfactors", - "title": "listFactors", - "type": "function", - }, - "auth-admin-listproviders": { - "id": "auth-admin-listproviders", - "product": "auth", - "slug": "auth-admin-listproviders", - "title": "listProviders", - "type": "function", - }, - "auth-admin-listusers": { - "id": "auth-admin-listusers", - "product": "auth", - "slug": "auth-admin-listusers", - "title": "listUsers", - "type": "function", - }, - "auth-admin-signout": { - "id": "auth-admin-signout", - "product": "auth", - "slug": "auth-admin-signout", - "title": "signOut", - "type": "function", - }, - "auth-admin-updateprovider": { - "id": "auth-admin-updateprovider", - "product": "auth", - "slug": "auth-admin-updateprovider", - "title": "updateProvider", - "type": "function", - }, - "auth-admin-updateuserbyid": { - "id": "auth-admin-updateuserbyid", - "product": "auth", - "slug": "auth-admin-updateuserbyid", - "title": "updateUserById", - "type": "function", - }, - "auth-dispose": { - "id": "auth-dispose", - "product": "auth", - "slug": "auth-dispose", - "title": "dispose", - "type": "function", - }, - "auth-exchangecodeforsession": { - "id": "auth-exchangecodeforsession", - "product": "auth", - "slug": "auth-exchangecodeforsession", - "title": "exchangeCodeForSession", - "type": "function", - }, - "auth-getclaims": { - "id": "auth-getclaims", - "product": "auth", - "slug": "auth-getclaims", - "title": "getClaims", - "type": "function", - }, - "auth-getsession": { - "id": "auth-getsession", - "product": "auth", - "slug": "auth-getsession", - "title": "getSession", - "type": "function", - }, - "auth-getuser": { - "id": "auth-getuser", - "product": "auth", - "slug": "auth-getuser", - "title": "getUser", - "type": "function", - }, - "auth-getuseridentities": { - "id": "auth-getuseridentities", - "product": "auth", - "slug": "auth-getuseridentities", - "title": "getUserIdentities", - "type": "function", - }, - "auth-initialize": { - "id": "auth-initialize", - "product": "auth", - "slug": "auth-initialize", - "title": "initialize", - "type": "function", - }, - "auth-linkidentity": { - "id": "auth-linkidentity", - "product": "auth", - "slug": "auth-linkidentity", - "title": "linkIdentity", - "type": "function", - }, - "auth-mfa": { - "id": "auth-mfa", - "slug": "auth-mfa", - "title": "Auth MFA", - "type": "function", - }, - "auth-mfa-challenge": { - "id": "auth-mfa-challenge", - "product": "auth", - "slug": "auth-mfa-challenge", - "title": "challenge", - "type": "function", - }, - "auth-mfa-challengeandverify": { - "id": "auth-mfa-challengeandverify", - "product": "auth", - "slug": "auth-mfa-challengeandverify", - "title": "challengeAndVerify", - "type": "function", - }, - "auth-mfa-enroll": { - "id": "auth-mfa-enroll", - "product": "auth", - "slug": "auth-mfa-enroll", - "title": "enroll", - "type": "function", - }, - "auth-mfa-getauthenticatorassurancelevel": { - "id": "auth-mfa-getauthenticatorassurancelevel", - "product": "auth", - "slug": "auth-mfa-getauthenticatorassurancelevel", - "title": "getAuthenticatorAssuranceLevel", - "type": "function", - }, - "auth-mfa-listfactors": { - "id": "auth-mfa-listfactors", - "product": "auth", - "slug": "auth-mfa-listfactors", - "title": "listFactors", - "type": "function", - }, - "auth-mfa-unenroll": { - "id": "auth-mfa-unenroll", - "product": "auth", - "slug": "auth-mfa-unenroll", - "title": "unenroll", - "type": "function", - }, - "auth-mfa-verify": { - "id": "auth-mfa-verify", - "product": "auth", - "slug": "auth-mfa-verify", - "title": "verify", - "type": "function", - }, - "auth-onauthstatechange": { - "id": "auth-onauthstatechange", - "product": "auth", - "slug": "auth-onauthstatechange", - "title": "onAuthStateChange", - "type": "function", - }, - "auth-passkey": { - "id": "auth-passkey", - "slug": "auth-passkey", - "title": "Auth Passkey", - "type": "function", - }, - "auth-passkey-delete": { - "id": "auth-passkey-delete", - "product": "auth", - "slug": "auth-passkey-delete", - "title": "delete", - "type": "function", - }, - "auth-passkey-list": { - "id": "auth-passkey-list", - "product": "auth", - "slug": "auth-passkey-list", - "title": "list", - "type": "function", - }, - "auth-passkey-startauthentication": { - "id": "auth-passkey-startauthentication", - "product": "auth", - "slug": "auth-passkey-startauthentication", - "title": "startAuthentication", - "type": "function", - }, - "auth-passkey-startregistration": { - "id": "auth-passkey-startregistration", - "product": "auth", - "slug": "auth-passkey-startregistration", - "title": "startRegistration", - "type": "function", - }, - "auth-passkey-update": { - "id": "auth-passkey-update", - "product": "auth", - "slug": "auth-passkey-update", - "title": "update", - "type": "function", - }, - "auth-passkey-verifyauthentication": { - "id": "auth-passkey-verifyauthentication", - "product": "auth", - "slug": "auth-passkey-verifyauthentication", - "title": "verifyAuthentication", - "type": "function", - }, - "auth-passkey-verifyregistration": { - "id": "auth-passkey-verifyregistration", - "product": "auth", - "slug": "auth-passkey-verifyregistration", - "title": "verifyRegistration", - "type": "function", - }, - "auth-reauthenticate": { - "id": "auth-reauthenticate", - "product": "auth", - "slug": "auth-reauthenticate", - "title": "reauthenticate", - "type": "function", - }, - "auth-refreshsession": { - "id": "auth-refreshsession", - "product": "auth", - "slug": "auth-refreshsession", - "title": "refreshSession", - "type": "function", - }, - "auth-registerpasskey": { - "id": "auth-registerpasskey", - "product": "auth", - "slug": "auth-registerpasskey", - "title": "registerPasskey", - "type": "function", - }, - "auth-resend": { - "id": "auth-resend", - "product": "auth", - "slug": "auth-resend", - "title": "resend", - "type": "function", - }, - "auth-resetpasswordforemail": { - "id": "auth-resetpasswordforemail", - "product": "auth", - "slug": "auth-resetpasswordforemail", - "title": "resetPasswordForEmail", - "type": "function", - }, - "auth-setsession": { - "id": "auth-setsession", - "product": "auth", - "slug": "auth-setsession", - "title": "setSession", - "type": "function", - }, - "auth-signinanonymously": { - "id": "auth-signinanonymously", - "product": "auth", - "slug": "auth-signinanonymously", - "title": "signInAnonymously", - "type": "function", - }, - "auth-signinwithidtoken": { - "id": "auth-signinwithidtoken", - "product": "auth", - "slug": "auth-signinwithidtoken", - "title": "signInWithIdToken", - "type": "function", - }, - "auth-signinwithoauth": { - "id": "auth-signinwithoauth", - "product": "auth", - "slug": "auth-signinwithoauth", - "title": "signInWithOAuth", - "type": "function", - }, - "auth-signinwithotp": { - "id": "auth-signinwithotp", - "product": "auth", - "slug": "auth-signinwithotp", - "title": "signInWithOtp", - "type": "function", - }, - "auth-signinwithpasskey": { - "id": "auth-signinwithpasskey", - "product": "auth", - "slug": "auth-signinwithpasskey", - "title": "signInWithPasskey", - "type": "function", - }, - "auth-signinwithpassword": { - "id": "auth-signinwithpassword", - "product": "auth", - "slug": "auth-signinwithpassword", - "title": "signInWithPassword", - "type": "function", - }, - "auth-signinwithsso": { - "id": "auth-signinwithsso", - "product": "auth", - "slug": "auth-signinwithsso", - "title": "signInWithSSO", - "type": "function", - }, - "auth-signinwithweb3": { - "id": "auth-signinwithweb3", - "product": "auth", - "slug": "auth-signinwithweb3", - "title": "signInWithWeb3", - "type": "function", - }, - "auth-signout": { - "id": "auth-signout", - "product": "auth", - "slug": "auth-signout", - "title": "signOut", - "type": "function", - }, - "auth-signup": { - "id": "auth-signup", - "product": "auth", - "slug": "auth-signup", - "title": "signUp", - "type": "function", - }, - "auth-startautorefresh": { - "id": "auth-startautorefresh", - "product": "auth", - "slug": "auth-startautorefresh", - "title": "startAutoRefresh", - "type": "function", - }, - "auth-stopautorefresh": { - "id": "auth-stopautorefresh", - "product": "auth", - "slug": "auth-stopautorefresh", - "title": "stopAutoRefresh", - "type": "function", - }, - "auth-unlinkidentity": { - "id": "auth-unlinkidentity", - "product": "auth", - "slug": "auth-unlinkidentity", - "title": "unlinkIdentity", - "type": "function", - }, - "auth-updateuser": { - "id": "auth-updateuser", - "product": "auth", - "slug": "auth-updateuser", - "title": "updateUser", - "type": "function", - }, - "auth-verifyotp": { - "id": "auth-verifyotp", - "product": "auth", - "slug": "auth-verifyotp", - "title": "verifyOtp", - "type": "function", - }, - "channel": { - "id": "channel", - "product": "realtime", - "slug": "channel", - "title": "channel", - "type": "function", - }, - "connect": { - "id": "connect", - "product": "realtime", - "slug": "connect", - "title": "connect", - "type": "function", - }, - "connectionstate": { - "id": "connectionstate", - "product": "realtime", - "slug": "connectionstate", - "title": "connectionState", - "type": "function", - }, - "database": { - "title": "Database", - "type": "category", - }, - "delete": { - "id": "delete", - "product": "database", - "slug": "delete", - "title": "delete", - "type": "function", - }, - "disconnect": { - "id": "disconnect", - "product": "realtime", - "slug": "disconnect", - "title": "disconnect", - "type": "function", - }, - "endpointurl": { - "id": "endpointurl", - "product": "realtime", - "slug": "endpointurl", - "title": "endpointURL", - "type": "function", - }, - "file-buckets": { - "id": "file-buckets", - "slug": "file-buckets", - "title": "File Buckets", - "type": "function", - }, - "file-buckets-copy": { - "id": "file-buckets-copy", - "product": "storage", - "slug": "file-buckets-copy", - "title": "copy", - "type": "function", - }, - "file-buckets-createbucket": { - "id": "file-buckets-createbucket", - "product": "storage", - "slug": "file-buckets-createbucket", - "title": "createBucket", - "type": "function", - }, - "file-buckets-createsigneduploadurl": { - "id": "file-buckets-createsigneduploadurl", - "product": "storage", - "slug": "file-buckets-createsigneduploadurl", - "title": "createSignedUploadUrl", - "type": "function", - }, - "file-buckets-createsignedurl": { - "id": "file-buckets-createsignedurl", - "product": "storage", - "slug": "file-buckets-createsignedurl", - "title": "createSignedUrl", - "type": "function", - }, - "file-buckets-createsignedurls": { - "id": "file-buckets-createsignedurls", - "product": "storage", - "slug": "file-buckets-createsignedurls", - "title": "createSignedUrls", - "type": "function", - }, - "file-buckets-deletebucket": { - "id": "file-buckets-deletebucket", - "product": "storage", - "slug": "file-buckets-deletebucket", - "title": "deleteBucket", - "type": "function", - }, - "file-buckets-download": { - "id": "file-buckets-download", - "product": "storage", - "slug": "file-buckets-download", - "title": "download", - "type": "function", - }, - "file-buckets-emptybucket": { - "id": "file-buckets-emptybucket", - "product": "storage", - "slug": "file-buckets-emptybucket", - "title": "emptyBucket", - "type": "function", - }, - "file-buckets-exists": { - "id": "file-buckets-exists", - "product": "storage", - "slug": "file-buckets-exists", - "title": "exists", - "type": "function", - }, - "file-buckets-from": { - "id": "file-buckets-from", - "product": "storage", - "slug": "file-buckets-from", - "title": "from", - "type": "function", - }, - "file-buckets-getbucket": { - "id": "file-buckets-getbucket", - "product": "storage", - "slug": "file-buckets-getbucket", - "title": "getBucket", - "type": "function", - }, - "file-buckets-getpublicurl": { - "id": "file-buckets-getpublicurl", - "product": "storage", - "slug": "file-buckets-getpublicurl", - "title": "getPublicUrl", - "type": "function", - }, - "file-buckets-info": { - "id": "file-buckets-info", - "product": "storage", - "slug": "file-buckets-info", - "title": "info", - "type": "function", - }, - "file-buckets-list": { - "id": "file-buckets-list", - "product": "storage", - "slug": "file-buckets-list", - "title": "list", - "type": "function", - }, - "file-buckets-listbuckets": { - "id": "file-buckets-listbuckets", - "product": "storage", - "slug": "file-buckets-listbuckets", - "title": "listBuckets", - "type": "function", - }, - "file-buckets-listv2": { - "id": "file-buckets-listv2", - "product": "storage", - "slug": "file-buckets-listv2", - "title": "listV2", - "type": "function", - }, - "file-buckets-move": { - "id": "file-buckets-move", - "product": "storage", - "slug": "file-buckets-move", - "title": "move", - "type": "function", - }, - "file-buckets-remove": { - "id": "file-buckets-remove", - "product": "storage", - "slug": "file-buckets-remove", - "title": "remove", - "type": "function", - }, - "file-buckets-update": { - "id": "file-buckets-update", - "product": "storage", - "slug": "file-buckets-update", - "title": "update", - "type": "function", - }, - "file-buckets-updatebucket": { - "id": "file-buckets-updatebucket", - "product": "storage", - "slug": "file-buckets-updatebucket", - "title": "updateBucket", - "type": "function", - }, - "file-buckets-upload": { - "id": "file-buckets-upload", - "product": "storage", - "slug": "file-buckets-upload", - "title": "upload", - "type": "function", - }, - "file-buckets-uploadtosignedurl": { - "id": "file-buckets-uploadtosignedurl", - "product": "storage", - "slug": "file-buckets-uploadtosignedurl", - "title": "uploadToSignedUrl", - "type": "function", - }, - "from": { - "id": "from", - "product": "database", - "slug": "from", - "title": "from", - "type": "function", - }, - "functions": { - "title": "Edge Functions", - "type": "category", - }, - "functions-corsheaders": { - "id": "functions-corsheaders", - "product": "edge-functions", - "slug": "functions-corsheaders", - "title": "corsHeaders", - "type": "function", - }, - "functions-invoke": { - "id": "functions-invoke", - "product": "edge-functions", - "slug": "functions-invoke", - "title": "invoke", - "type": "function", - }, - "functions-setauth": { - "id": "functions-setauth", - "product": "edge-functions", - "slug": "functions-setauth", - "title": "setAuth", - "type": "function", - }, - "geojson": { - "id": "geojson", - "product": "database", - "slug": "geojson", - "title": "geojson", - "type": "function", - }, - "getchannels": { - "id": "getchannels", - "product": "realtime", - "slug": "getchannels", - "title": "getChannels", - "type": "function", - }, - "getwebsocketconstructor": { - "id": "getwebsocketconstructor", - "product": "realtime", - "slug": "getwebsocketconstructor", - "title": "getWebSocketConstructor", - "type": "function", - }, - "httpsend": { - "id": "httpsend", - "product": "realtime", - "slug": "httpsend", - "title": "httpSend", - "type": "function", - }, - "initializing": { - "id": "initializing", - "slug": "initializing", - "title": "Initializing", - "type": "function", - }, - "insert": { - "id": "insert", - "product": "database", - "slug": "insert", - "title": "insert", - "type": "function", - }, - "installing": { - "id": "installing", - "slug": "installing", - "title": "Installing", - "type": "markdown", - }, - "introduction": { - "id": "introduction", - "slug": "introduction", - "title": "Introduction", - "type": "markdown", - }, - "isconnected": { - "id": "isconnected", - "product": "realtime", - "slug": "isconnected", - "title": "isConnected", - "type": "function", - }, - "isconnecting": { - "id": "isconnecting", - "product": "realtime", - "slug": "isconnecting", - "title": "isConnecting", - "type": "function", - }, - "isdisconnecting": { - "id": "isdisconnecting", - "product": "realtime", - "slug": "isdisconnecting", - "title": "isDisconnecting", - "type": "function", - }, - "iswebsocketsupported": { - "id": "iswebsocketsupported", - "product": "realtime", - "slug": "iswebsocketsupported", - "title": "isWebSocketSupported", - "type": "function", - }, - "log": { - "id": "log", - "product": "realtime", - "slug": "log", - "title": "log", - "type": "function", - }, - "maxaffected": { - "id": "maxaffected", - "product": "database", - "slug": "maxaffected", - "title": "maxAffected", - "type": "function", - }, - "oauth-admin": { - "id": "oauth-admin", - "slug": "oauth-admin", - "title": "OAuth Admin", - "type": "function", - }, - "oauth-admin-createclient": { - "id": "oauth-admin-createclient", - "product": "auth", - "slug": "oauth-admin-createclient", - "title": "createClient", - "type": "function", - }, - "oauth-admin-deleteclient": { - "id": "oauth-admin-deleteclient", - "product": "auth", - "slug": "oauth-admin-deleteclient", - "title": "deleteClient", - "type": "function", - }, - "oauth-admin-getclient": { - "id": "oauth-admin-getclient", - "product": "auth", - "slug": "oauth-admin-getclient", - "title": "getClient", - "type": "function", - }, - "oauth-admin-listclients": { - "id": "oauth-admin-listclients", - "product": "auth", - "slug": "oauth-admin-listclients", - "title": "listClients", - "type": "function", - }, - "oauth-admin-regenerateclientsecret": { - "id": "oauth-admin-regenerateclientsecret", - "product": "auth", - "slug": "oauth-admin-regenerateclientsecret", - "title": "regenerateClientSecret", - "type": "function", - }, - "oauth-admin-updateclient": { - "id": "oauth-admin-updateclient", - "product": "auth", - "slug": "oauth-admin-updateclient", - "title": "updateClient", - "type": "function", - }, - "oauth-server": { - "id": "oauth-server", - "slug": "oauth-server", - "title": "OAuth Server", - "type": "function", - }, - "oauth-server-approveauthorization": { - "id": "oauth-server-approveauthorization", - "product": "auth", - "slug": "oauth-server-approveauthorization", - "title": "approveAuthorization", - "type": "function", - }, - "oauth-server-denyauthorization": { - "id": "oauth-server-denyauthorization", - "product": "auth", - "slug": "oauth-server-denyauthorization", - "title": "denyAuthorization", - "type": "function", - }, - "oauth-server-getauthorizationdetails": { - "id": "oauth-server-getauthorizationdetails", - "product": "auth", - "slug": "oauth-server-getauthorizationdetails", - "title": "getAuthorizationDetails", - "type": "function", - }, - "oauth-server-listgrants": { - "id": "oauth-server-listgrants", - "product": "auth", - "slug": "oauth-server-listgrants", - "title": "listGrants", - "type": "function", - }, - "oauth-server-revokegrant": { - "id": "oauth-server-revokegrant", - "product": "auth", - "slug": "oauth-server-revokegrant", - "title": "revokeGrant", - "type": "function", - }, - "on": { - "id": "on", - "product": "realtime", - "slug": "on", - "title": "on", - "type": "function", - }, - "onheartbeat": { - "id": "onheartbeat", - "product": "realtime", - "slug": "onheartbeat", - "title": "onHeartbeat", - "type": "function", - }, - "passkey-admin": { - "id": "passkey-admin", - "slug": "passkey-admin", - "title": "Passkey admin", - "type": "function", - }, - "passkey-admin-deletepasskey": { - "id": "passkey-admin-deletepasskey", - "product": "auth", - "slug": "passkey-admin-deletepasskey", - "title": "deletePasskey", - "type": "function", - }, - "passkey-admin-listpasskeys": { - "id": "passkey-admin-listpasskeys", - "product": "auth", - "slug": "passkey-admin-listpasskeys", - "title": "listPasskeys", - "type": "function", - }, - "presencestate": { - "id": "presencestate", - "product": "realtime", - "slug": "presencestate", - "title": "presenceState", - "type": "function", - }, - "push": { - "id": "push", - "product": "realtime", - "slug": "push", - "title": "push", - "type": "function", - }, - "realtime": { - "title": "Realtime", - "type": "category", - }, - "removeallchannels": { - "id": "removeallchannels", - "product": "realtime", - "slug": "removeallchannels", - "title": "removeAllChannels", - "type": "function", - }, - "removechannel": { - "id": "removechannel", - "product": "realtime", - "slug": "removechannel", - "title": "removeChannel", - "type": "function", - }, - "retry": { - "id": "retry", - "product": "database", - "slug": "retry", - "title": "retry", - "type": "function", - }, - "returns": { - "id": "returns", - "product": "database", - "slug": "returns", - "title": "returns", - "type": "function", - }, - "rollback": { - "id": "rollback", - "product": "database", - "slug": "rollback", - "title": "rollback", - "type": "function", - }, - "rpc": { - "id": "rpc", - "product": "database", - "slug": "rpc", - "title": "rpc", - "type": "function", - }, - "schema": { - "id": "schema", - "product": "database", - "slug": "schema", - "title": "schema", - "type": "function", - }, - "select": { - "id": "select", - "product": "database", - "slug": "select", - "title": "select", - "type": "function", - }, - "send": { - "id": "send", - "product": "realtime", - "slug": "send", - "title": "send", - "type": "function", - }, - "sendheartbeat": { - "id": "sendheartbeat", - "product": "realtime", - "slug": "sendheartbeat", - "title": "sendHeartbeat", - "type": "function", - }, - "setauth": { - "id": "setauth", - "product": "realtime", - "slug": "setauth", - "title": "setAuth", - "type": "function", - }, - "setheader": { - "id": "setheader", - "product": "database", - "slug": "setheader", - "title": "setHeader", - "type": "function", - }, - "storage": { - "title": "Storage", - "type": "category", - }, - "subscribe": { - "id": "subscribe", - "product": "realtime", - "slug": "subscribe", - "title": "subscribe", - "type": "function", - }, - "teardown": { - "id": "teardown", - "product": "realtime", - "slug": "teardown", - "title": "teardown", - "type": "function", - }, - "throwonerror": { - "id": "throwonerror", - "product": "database", - "slug": "throwonerror", - "title": "throwOnError", - "type": "function", - }, - "track": { - "id": "track", - "product": "realtime", - "slug": "track", - "title": "track", - "type": "function", - }, - "typescript-support": { - "id": "typescript-support", - "slug": "typescript-support", - "title": "TypeScript support", - "type": "markdown", - }, - "unsubscribe": { - "id": "unsubscribe", - "product": "realtime", - "slug": "unsubscribe", - "title": "unsubscribe", - "type": "function", - }, - "untrack": { - "id": "untrack", - "product": "realtime", - "slug": "untrack", - "title": "untrack", - "type": "function", - }, - "update": { - "id": "update", - "product": "database", - "slug": "update", - "title": "update", - "type": "function", - }, - "updatejoinpayload": { - "id": "updatejoinpayload", - "product": "realtime", - "slug": "updatejoinpayload", - "title": "updateJoinPayload", - "type": "function", - }, - "upsert": { - "id": "upsert", - "product": "database", - "slug": "upsert", - "title": "upsert", - "type": "function", - }, - "using-filters": { - "id": "using-filters", - "slug": "using-filters", - "title": "Using Filters", - "type": "function", - }, - "using-filters-containedby": { - "id": "using-filters-containedby", - "product": "database", - "slug": "using-filters-containedby", - "title": "containedBy", - "type": "function", - }, - "using-filters-contains": { - "id": "using-filters-contains", - "product": "database", - "slug": "using-filters-contains", - "title": "contains", - "type": "function", - }, - "using-filters-eq": { - "id": "using-filters-eq", - "product": "database", - "slug": "using-filters-eq", - "title": "eq", - "type": "function", - }, - "using-filters-filter": { - "id": "using-filters-filter", - "product": "database", - "slug": "using-filters-filter", - "title": "filter", - "type": "function", - }, - "using-filters-gt": { - "id": "using-filters-gt", - "product": "database", - "slug": "using-filters-gt", - "title": "gt", - "type": "function", - }, - "using-filters-gte": { - "id": "using-filters-gte", - "product": "database", - "slug": "using-filters-gte", - "title": "gte", - "type": "function", - }, - "using-filters-ilike": { - "id": "using-filters-ilike", - "product": "database", - "slug": "using-filters-ilike", - "title": "ilike", - "type": "function", - }, - "using-filters-ilikeallof": { - "id": "using-filters-ilikeallof", - "product": "database", - "slug": "using-filters-ilikeallof", - "title": "ilikeAllOf", - "type": "function", - }, - "using-filters-ilikeanyof": { - "id": "using-filters-ilikeanyof", - "product": "database", - "slug": "using-filters-ilikeanyof", - "title": "ilikeAnyOf", - "type": "function", - }, - "using-filters-in": { - "id": "using-filters-in", - "product": "database", - "slug": "using-filters-in", - "title": "in", - "type": "function", - }, - "using-filters-is": { - "id": "using-filters-is", - "product": "database", - "slug": "using-filters-is", - "title": "is", - "type": "function", - }, - "using-filters-like": { - "id": "using-filters-like", - "product": "database", - "slug": "using-filters-like", - "title": "like", - "type": "function", - }, - "using-filters-likeallof": { - "id": "using-filters-likeallof", - "product": "database", - "slug": "using-filters-likeallof", - "title": "likeAllOf", - "type": "function", - }, - "using-filters-likeanyof": { - "id": "using-filters-likeanyof", - "product": "database", - "slug": "using-filters-likeanyof", - "title": "likeAnyOf", - "type": "function", - }, - "using-filters-lt": { - "id": "using-filters-lt", - "product": "database", - "slug": "using-filters-lt", - "title": "lt", - "type": "function", - }, - "using-filters-lte": { - "id": "using-filters-lte", - "product": "database", - "slug": "using-filters-lte", - "title": "lte", - "type": "function", - }, - "using-filters-match": { - "id": "using-filters-match", - "product": "database", - "slug": "using-filters-match", - "title": "match", - "type": "function", - }, - "using-filters-neq": { - "id": "using-filters-neq", - "product": "database", - "slug": "using-filters-neq", - "title": "neq", - "type": "function", - }, - "using-filters-not": { - "id": "using-filters-not", - "product": "database", - "slug": "using-filters-not", - "title": "not", - "type": "function", - }, - "using-filters-or": { - "id": "using-filters-or", - "product": "database", - "slug": "using-filters-or", - "title": "or", - "type": "function", - }, - "using-filters-overlaps": { - "id": "using-filters-overlaps", - "product": "database", - "slug": "using-filters-overlaps", - "title": "overlaps", - "type": "function", - }, - "using-filters-rangeadjacent": { - "id": "using-filters-rangeadjacent", - "product": "database", - "slug": "using-filters-rangeadjacent", - "title": "rangeAdjacent", - "type": "function", - }, - "using-filters-rangegt": { - "id": "using-filters-rangegt", - "product": "database", - "slug": "using-filters-rangegt", - "title": "rangeGt", - "type": "function", - }, - "using-filters-rangegte": { - "id": "using-filters-rangegte", - "product": "database", - "slug": "using-filters-rangegte", - "title": "rangeGte", - "type": "function", - }, - "using-filters-rangelt": { - "id": "using-filters-rangelt", - "product": "database", - "slug": "using-filters-rangelt", - "title": "rangeLt", - "type": "function", - }, - "using-filters-rangelte": { - "id": "using-filters-rangelte", - "product": "database", - "slug": "using-filters-rangelte", - "title": "rangeLte", - "type": "function", - }, - "using-filters-textsearch": { - "id": "using-filters-textsearch", - "product": "database", - "slug": "using-filters-textsearch", - "title": "textSearch", - "type": "function", - }, - "using-modifiers": { - "id": "using-modifiers", - "slug": "using-modifiers", - "title": "Using modifiers", - "type": "function", - }, - "using-modifiers-abortsignal": { - "id": "using-modifiers-abortsignal", - "product": "database", - "slug": "using-modifiers-abortsignal", - "title": "abortSignal", - "type": "function", - }, - "using-modifiers-csv": { - "id": "using-modifiers-csv", - "product": "database", - "slug": "using-modifiers-csv", - "title": "csv", - "type": "function", - }, - "using-modifiers-explain": { - "id": "using-modifiers-explain", - "product": "database", - "slug": "using-modifiers-explain", - "title": "explain", - "type": "function", - }, - "using-modifiers-limit": { - "id": "using-modifiers-limit", - "product": "database", - "slug": "using-modifiers-limit", - "title": "limit", - "type": "function", - }, - "using-modifiers-maybesingle": { - "id": "using-modifiers-maybesingle", - "product": "database", - "slug": "using-modifiers-maybesingle", - "title": "maybeSingle", - "type": "function", - }, - "using-modifiers-order": { - "id": "using-modifiers-order", - "product": "database", - "slug": "using-modifiers-order", - "title": "order", - "type": "function", - }, - "using-modifiers-overridetypes": { - "id": "using-modifiers-overridetypes", - "product": "database", - "slug": "using-modifiers-overridetypes", - "title": "overrideTypes", - "type": "function", - }, - "using-modifiers-range": { - "id": "using-modifiers-range", - "product": "database", - "slug": "using-modifiers-range", - "title": "range", - "type": "function", - }, - "using-modifiers-returns": { - "id": "using-modifiers-returns", - "product": "database", - "slug": "using-modifiers-returns", - "title": "returns", - "type": "function", - }, - "using-modifiers-select": { - "id": "using-modifiers-select", - "product": "database", - "slug": "using-modifiers-select", - "title": "select", - "type": "function", - }, - "using-modifiers-single": { - "id": "using-modifiers-single", - "product": "database", - "slug": "using-modifiers-single", - "title": "single", - "type": "function", - }, - "using-modifiers-stripnulls": { - "id": "using-modifiers-stripnulls", - "product": "database", - "slug": "using-modifiers-stripnulls", - "title": "stripNulls", - "type": "function", - }, - "vector-buckets": { - "id": "vector-buckets", - "slug": "vector-buckets", - "title": "Vector Buckets", - "type": "function", - }, - "vector-buckets-createbucket": { - "id": "vector-buckets-createbucket", - "product": "storage", - "slug": "vector-buckets-createbucket", - "title": "createBucket", - "type": "function", - }, - "vector-buckets-createindex": { - "id": "vector-buckets-createindex", - "product": "storage", - "slug": "vector-buckets-createindex", - "title": "createIndex", - "type": "function", - }, - "vector-buckets-deletebucket": { - "id": "vector-buckets-deletebucket", - "product": "storage", - "slug": "vector-buckets-deletebucket", - "title": "deleteBucket", - "type": "function", - }, - "vector-buckets-deleteindex": { - "id": "vector-buckets-deleteindex", - "product": "storage", - "slug": "vector-buckets-deleteindex", - "title": "deleteIndex", - "type": "function", - }, - "vector-buckets-deletevectors": { - "id": "vector-buckets-deletevectors", - "product": "storage", - "slug": "vector-buckets-deletevectors", - "title": "deleteVectors", - "type": "function", - }, - "vector-buckets-from": { - "id": "vector-buckets-from", - "product": "storage", - "slug": "vector-buckets-from", - "title": "from", - "type": "function", - }, - "vector-buckets-getbucket": { - "id": "vector-buckets-getbucket", - "product": "storage", - "slug": "vector-buckets-getbucket", - "title": "getBucket", - "type": "function", - }, - "vector-buckets-getindex": { - "id": "vector-buckets-getindex", - "product": "storage", - "slug": "vector-buckets-getindex", - "title": "getIndex", - "type": "function", - }, - "vector-buckets-getvectors": { - "id": "vector-buckets-getvectors", - "product": "storage", - "slug": "vector-buckets-getvectors", - "title": "getVectors", - "type": "function", - }, - "vector-buckets-index": { - "id": "vector-buckets-index", - "product": "storage", - "slug": "vector-buckets-index", - "title": "index", - "type": "function", - }, - "vector-buckets-listbuckets": { - "id": "vector-buckets-listbuckets", - "product": "storage", - "slug": "vector-buckets-listbuckets", - "title": "listBuckets", - "type": "function", - }, - "vector-buckets-listindexes": { - "id": "vector-buckets-listindexes", - "product": "storage", - "slug": "vector-buckets-listindexes", - "title": "listIndexes", - "type": "function", - }, - "vector-buckets-listvectors": { - "id": "vector-buckets-listvectors", - "product": "storage", - "slug": "vector-buckets-listvectors", - "title": "listVectors", - "type": "function", - }, - "vector-buckets-putvectors": { - "id": "vector-buckets-putvectors", - "product": "storage", - "slug": "vector-buckets-putvectors", - "title": "putVectors", - "type": "function", - }, - "vector-buckets-queryvectors": { - "id": "vector-buckets-queryvectors", - "product": "storage", - "slug": "vector-buckets-queryvectors", - "title": "queryVectors", - "type": "function", - }, - }, - "flat": [ - { - "id": "introduction", - "slug": "introduction", - "title": "Introduction", - "type": "markdown", - }, - { - "id": "installing", - "slug": "installing", - "title": "Installing", - "type": "markdown", - }, - { - "id": "initializing", - "slug": "initializing", - "title": "Initializing", - "type": "function", - }, - { - "id": "typescript-support", - "slug": "typescript-support", - "title": "TypeScript support", - "type": "markdown", - }, - { - "title": "Database", - "type": "category", - }, - { - "id": "delete", - "product": "database", - "slug": "delete", - "title": "delete", - "type": "function", - }, - { - "id": "from", - "product": "database", - "slug": "from", - "title": "from", - "type": "function", - }, - { - "id": "geojson", - "product": "database", - "slug": "geojson", - "title": "geojson", - "type": "function", - }, - { - "id": "insert", - "product": "database", - "slug": "insert", - "title": "insert", - "type": "function", - }, - { - "id": "maxaffected", - "product": "database", - "slug": "maxaffected", - "title": "maxAffected", - "type": "function", - }, - { - "id": "retry", - "product": "database", - "slug": "retry", - "title": "retry", - "type": "function", - }, - { - "id": "returns", - "product": "database", - "slug": "returns", - "title": "returns", - "type": "function", - }, - { - "id": "rollback", - "product": "database", - "slug": "rollback", - "title": "rollback", - "type": "function", - }, - { - "id": "rpc", - "product": "database", - "slug": "rpc", - "title": "rpc", - "type": "function", - }, - { - "id": "schema", - "product": "database", - "slug": "schema", - "title": "schema", - "type": "function", - }, - { - "id": "select", - "product": "database", - "slug": "select", - "title": "select", - "type": "function", - }, - { - "id": "setheader", - "product": "database", - "slug": "setheader", - "title": "setHeader", - "type": "function", - }, - { - "id": "throwonerror", - "product": "database", - "slug": "throwonerror", - "title": "throwOnError", - "type": "function", - }, - { - "id": "update", - "product": "database", - "slug": "update", - "title": "update", - "type": "function", - }, - { - "id": "upsert", - "product": "database", - "slug": "upsert", - "title": "upsert", - "type": "function", - }, - { - "id": "using-filters", - "slug": "using-filters", - "title": "Using Filters", - "type": "function", - }, - { - "id": "using-filters-containedby", - "product": "database", - "slug": "using-filters-containedby", - "title": "containedBy", - "type": "function", - }, - { - "id": "using-filters-contains", - "product": "database", - "slug": "using-filters-contains", - "title": "contains", - "type": "function", - }, - { - "id": "using-filters-eq", - "product": "database", - "slug": "using-filters-eq", - "title": "eq", - "type": "function", - }, - { - "id": "using-filters-filter", - "product": "database", - "slug": "using-filters-filter", - "title": "filter", - "type": "function", - }, - { - "id": "using-filters-gt", - "product": "database", - "slug": "using-filters-gt", - "title": "gt", - "type": "function", - }, - { - "id": "using-filters-gte", - "product": "database", - "slug": "using-filters-gte", - "title": "gte", - "type": "function", - }, - { - "id": "using-filters-ilike", - "product": "database", - "slug": "using-filters-ilike", - "title": "ilike", - "type": "function", - }, - { - "id": "using-filters-ilikeallof", - "product": "database", - "slug": "using-filters-ilikeallof", - "title": "ilikeAllOf", - "type": "function", - }, - { - "id": "using-filters-ilikeanyof", - "product": "database", - "slug": "using-filters-ilikeanyof", - "title": "ilikeAnyOf", - "type": "function", - }, - { - "id": "using-filters-in", - "product": "database", - "slug": "using-filters-in", - "title": "in", - "type": "function", - }, - { - "id": "using-filters-is", - "product": "database", - "slug": "using-filters-is", - "title": "is", - "type": "function", - }, - { - "id": "using-filters-like", - "product": "database", - "slug": "using-filters-like", - "title": "like", - "type": "function", - }, - { - "id": "using-filters-likeallof", - "product": "database", - "slug": "using-filters-likeallof", - "title": "likeAllOf", - "type": "function", - }, - { - "id": "using-filters-likeanyof", - "product": "database", - "slug": "using-filters-likeanyof", - "title": "likeAnyOf", - "type": "function", - }, - { - "id": "using-filters-lt", - "product": "database", - "slug": "using-filters-lt", - "title": "lt", - "type": "function", - }, - { - "id": "using-filters-lte", - "product": "database", - "slug": "using-filters-lte", - "title": "lte", - "type": "function", - }, - { - "id": "using-filters-match", - "product": "database", - "slug": "using-filters-match", - "title": "match", - "type": "function", - }, - { - "id": "using-filters-neq", - "product": "database", - "slug": "using-filters-neq", - "title": "neq", - "type": "function", - }, - { - "id": "using-filters-not", - "product": "database", - "slug": "using-filters-not", - "title": "not", - "type": "function", - }, - { - "id": "using-filters-or", - "product": "database", - "slug": "using-filters-or", - "title": "or", - "type": "function", - }, - { - "id": "using-filters-overlaps", - "product": "database", - "slug": "using-filters-overlaps", - "title": "overlaps", - "type": "function", - }, - { - "id": "using-filters-rangeadjacent", - "product": "database", - "slug": "using-filters-rangeadjacent", - "title": "rangeAdjacent", - "type": "function", - }, - { - "id": "using-filters-rangegt", - "product": "database", - "slug": "using-filters-rangegt", - "title": "rangeGt", - "type": "function", - }, - { - "id": "using-filters-rangegte", - "product": "database", - "slug": "using-filters-rangegte", - "title": "rangeGte", - "type": "function", - }, - { - "id": "using-filters-rangelt", - "product": "database", - "slug": "using-filters-rangelt", - "title": "rangeLt", - "type": "function", - }, - { - "id": "using-filters-rangelte", - "product": "database", - "slug": "using-filters-rangelte", - "title": "rangeLte", - "type": "function", - }, - { - "id": "using-filters-textsearch", - "product": "database", - "slug": "using-filters-textsearch", - "title": "textSearch", - "type": "function", - }, - { - "id": "using-modifiers", - "slug": "using-modifiers", - "title": "Using modifiers", - "type": "function", - }, - { - "id": "using-modifiers-abortsignal", - "product": "database", - "slug": "using-modifiers-abortsignal", - "title": "abortSignal", - "type": "function", - }, - { - "id": "using-modifiers-csv", - "product": "database", - "slug": "using-modifiers-csv", - "title": "csv", - "type": "function", - }, - { - "id": "using-modifiers-explain", - "product": "database", - "slug": "using-modifiers-explain", - "title": "explain", - "type": "function", - }, - { - "id": "using-modifiers-limit", - "product": "database", - "slug": "using-modifiers-limit", - "title": "limit", - "type": "function", - }, - { - "id": "using-modifiers-maybesingle", - "product": "database", - "slug": "using-modifiers-maybesingle", - "title": "maybeSingle", - "type": "function", - }, - { - "id": "using-modifiers-order", - "product": "database", - "slug": "using-modifiers-order", - "title": "order", - "type": "function", - }, - { - "id": "using-modifiers-overridetypes", - "product": "database", - "slug": "using-modifiers-overridetypes", - "title": "overrideTypes", - "type": "function", - }, - { - "id": "using-modifiers-range", - "product": "database", - "slug": "using-modifiers-range", - "title": "range", - "type": "function", - }, - { - "id": "using-modifiers-returns", - "product": "database", - "slug": "using-modifiers-returns", - "title": "returns", - "type": "function", - }, - { - "id": "using-modifiers-select", - "product": "database", - "slug": "using-modifiers-select", - "title": "select", - "type": "function", - }, - { - "id": "using-modifiers-single", - "product": "database", - "slug": "using-modifiers-single", - "title": "single", - "type": "function", - }, - { - "id": "using-modifiers-stripnulls", - "product": "database", - "slug": "using-modifiers-stripnulls", - "title": "stripNulls", - "type": "function", - }, - { - "id": "auth", - "slug": "auth", - "title": "Overview", - "type": "function", - }, - { - "id": "auth-dispose", - "product": "auth", - "slug": "auth-dispose", - "title": "dispose", - "type": "function", - }, - { - "id": "auth-exchangecodeforsession", - "product": "auth", - "slug": "auth-exchangecodeforsession", - "title": "exchangeCodeForSession", - "type": "function", - }, - { - "id": "auth-getclaims", - "product": "auth", - "slug": "auth-getclaims", - "title": "getClaims", - "type": "function", - }, - { - "id": "auth-getsession", - "product": "auth", - "slug": "auth-getsession", - "title": "getSession", - "type": "function", - }, - { - "id": "auth-getuser", - "product": "auth", - "slug": "auth-getuser", - "title": "getUser", - "type": "function", - }, - { - "id": "auth-getuseridentities", - "product": "auth", - "slug": "auth-getuseridentities", - "title": "getUserIdentities", - "type": "function", - }, - { - "id": "auth-initialize", - "product": "auth", - "slug": "auth-initialize", - "title": "initialize", - "type": "function", - }, - { - "id": "auth-linkidentity", - "product": "auth", - "slug": "auth-linkidentity", - "title": "linkIdentity", - "type": "function", - }, - { - "id": "auth-onauthstatechange", - "product": "auth", - "slug": "auth-onauthstatechange", - "title": "onAuthStateChange", - "type": "function", - }, - { - "id": "auth-reauthenticate", - "product": "auth", - "slug": "auth-reauthenticate", - "title": "reauthenticate", - "type": "function", - }, - { - "id": "auth-refreshsession", - "product": "auth", - "slug": "auth-refreshsession", - "title": "refreshSession", - "type": "function", - }, - { - "id": "auth-registerpasskey", - "product": "auth", - "slug": "auth-registerpasskey", - "title": "registerPasskey", - "type": "function", - }, - { - "id": "auth-resend", - "product": "auth", - "slug": "auth-resend", - "title": "resend", - "type": "function", - }, - { - "id": "auth-resetpasswordforemail", - "product": "auth", - "slug": "auth-resetpasswordforemail", - "title": "resetPasswordForEmail", - "type": "function", - }, - { - "id": "auth-setsession", - "product": "auth", - "slug": "auth-setsession", - "title": "setSession", - "type": "function", - }, - { - "id": "auth-signinanonymously", - "product": "auth", - "slug": "auth-signinanonymously", - "title": "signInAnonymously", - "type": "function", - }, - { - "id": "auth-signinwithidtoken", - "product": "auth", - "slug": "auth-signinwithidtoken", - "title": "signInWithIdToken", - "type": "function", - }, - { - "id": "auth-signinwithoauth", - "product": "auth", - "slug": "auth-signinwithoauth", - "title": "signInWithOAuth", - "type": "function", - }, - { - "id": "auth-signinwithotp", - "product": "auth", - "slug": "auth-signinwithotp", - "title": "signInWithOtp", - "type": "function", - }, - { - "id": "auth-signinwithpasskey", - "product": "auth", - "slug": "auth-signinwithpasskey", - "title": "signInWithPasskey", - "type": "function", - }, - { - "id": "auth-signinwithpassword", - "product": "auth", - "slug": "auth-signinwithpassword", - "title": "signInWithPassword", - "type": "function", - }, - { - "id": "auth-signinwithsso", - "product": "auth", - "slug": "auth-signinwithsso", - "title": "signInWithSSO", - "type": "function", - }, - { - "id": "auth-signinwithweb3", - "product": "auth", - "slug": "auth-signinwithweb3", - "title": "signInWithWeb3", - "type": "function", - }, - { - "id": "auth-signout", - "product": "auth", - "slug": "auth-signout", - "title": "signOut", - "type": "function", - }, - { - "id": "auth-signup", - "product": "auth", - "slug": "auth-signup", - "title": "signUp", - "type": "function", - }, - { - "id": "auth-startautorefresh", - "product": "auth", - "slug": "auth-startautorefresh", - "title": "startAutoRefresh", - "type": "function", - }, - { - "id": "auth-stopautorefresh", - "product": "auth", - "slug": "auth-stopautorefresh", - "title": "stopAutoRefresh", - "type": "function", - }, - { - "id": "auth-unlinkidentity", - "product": "auth", - "slug": "auth-unlinkidentity", - "title": "unlinkIdentity", - "type": "function", - }, - { - "id": "auth-updateuser", - "product": "auth", - "slug": "auth-updateuser", - "title": "updateUser", - "type": "function", - }, - { - "id": "auth-verifyotp", - "product": "auth", - "slug": "auth-verifyotp", - "title": "verifyOtp", - "type": "function", - }, - { - "id": "auth-admin", - "slug": "auth-admin", - "title": "Overview", - "type": "function", - }, - { - "id": "auth-admin-createprovider", - "product": "auth", - "slug": "auth-admin-createprovider", - "title": "createProvider", - "type": "function", - }, - { - "id": "auth-admin-createuser", - "product": "auth", - "slug": "auth-admin-createuser", - "title": "createUser", - "type": "function", - }, - { - "id": "auth-admin-deletefactor", - "product": "auth", - "slug": "auth-admin-deletefactor", - "title": "deleteFactor", - "type": "function", - }, - { - "id": "auth-admin-deleteprovider", - "product": "auth", - "slug": "auth-admin-deleteprovider", - "title": "deleteProvider", - "type": "function", - }, - { - "id": "auth-admin-deleteuser", - "product": "auth", - "slug": "auth-admin-deleteuser", - "title": "deleteUser", - "type": "function", - }, - { - "id": "auth-admin-generatelink", - "product": "auth", - "slug": "auth-admin-generatelink", - "title": "generateLink", - "type": "function", - }, - { - "id": "auth-admin-getprovider", - "product": "auth", - "slug": "auth-admin-getprovider", - "title": "getProvider", - "type": "function", - }, - { - "id": "auth-admin-getuserbyid", - "product": "auth", - "slug": "auth-admin-getuserbyid", - "title": "getUserById", - "type": "function", - }, - { - "id": "auth-admin-inviteuserbyemail", - "product": "auth", - "slug": "auth-admin-inviteuserbyemail", - "title": "inviteUserByEmail", - "type": "function", - }, - { - "id": "auth-admin-listfactors", - "product": "auth", - "slug": "auth-admin-listfactors", - "title": "listFactors", - "type": "function", - }, - { - "id": "auth-admin-listproviders", - "product": "auth", - "slug": "auth-admin-listproviders", - "title": "listProviders", - "type": "function", - }, - { - "id": "auth-admin-listusers", - "product": "auth", - "slug": "auth-admin-listusers", - "title": "listUsers", - "type": "function", - }, - { - "id": "auth-admin-signout", - "product": "auth", - "slug": "auth-admin-signout", - "title": "signOut", - "type": "function", - }, - { - "id": "auth-admin-updateprovider", - "product": "auth", - "slug": "auth-admin-updateprovider", - "title": "updateProvider", - "type": "function", - }, - { - "id": "auth-admin-updateuserbyid", - "product": "auth", - "slug": "auth-admin-updateuserbyid", - "title": "updateUserById", - "type": "function", - }, - { - "id": "auth-mfa", - "slug": "auth-mfa", - "title": "Auth MFA", - "type": "function", - }, - { - "id": "auth-mfa-challenge", - "product": "auth", - "slug": "auth-mfa-challenge", - "title": "challenge", - "type": "function", - }, - { - "id": "auth-mfa-challengeandverify", - "product": "auth", - "slug": "auth-mfa-challengeandverify", - "title": "challengeAndVerify", - "type": "function", - }, - { - "id": "auth-mfa-enroll", - "product": "auth", - "slug": "auth-mfa-enroll", - "title": "enroll", - "type": "function", - }, - { - "id": "auth-mfa-getauthenticatorassurancelevel", - "product": "auth", - "slug": "auth-mfa-getauthenticatorassurancelevel", - "title": "getAuthenticatorAssuranceLevel", - "type": "function", - }, - { - "id": "auth-mfa-listfactors", - "product": "auth", - "slug": "auth-mfa-listfactors", - "title": "listFactors", - "type": "function", - }, - { - "id": "auth-mfa-unenroll", - "product": "auth", - "slug": "auth-mfa-unenroll", - "title": "unenroll", - "type": "function", - }, - { - "id": "auth-mfa-verify", - "product": "auth", - "slug": "auth-mfa-verify", - "title": "verify", - "type": "function", - }, - { - "id": "auth-passkey", - "slug": "auth-passkey", - "title": "Auth Passkey", - "type": "function", - }, - { - "id": "auth-passkey-delete", - "product": "auth", - "slug": "auth-passkey-delete", - "title": "delete", - "type": "function", - }, - { - "id": "auth-passkey-list", - "product": "auth", - "slug": "auth-passkey-list", - "title": "list", - "type": "function", - }, - { - "id": "auth-passkey-startauthentication", - "product": "auth", - "slug": "auth-passkey-startauthentication", - "title": "startAuthentication", - "type": "function", - }, - { - "id": "auth-passkey-startregistration", - "product": "auth", - "slug": "auth-passkey-startregistration", - "title": "startRegistration", - "type": "function", - }, - { - "id": "auth-passkey-update", - "product": "auth", - "slug": "auth-passkey-update", - "title": "update", - "type": "function", - }, - { - "id": "auth-passkey-verifyauthentication", - "product": "auth", - "slug": "auth-passkey-verifyauthentication", - "title": "verifyAuthentication", - "type": "function", - }, - { - "id": "auth-passkey-verifyregistration", - "product": "auth", - "slug": "auth-passkey-verifyregistration", - "title": "verifyRegistration", - "type": "function", - }, - { - "id": "oauth-admin", - "slug": "oauth-admin", - "title": "OAuth Admin", - "type": "function", - }, - { - "id": "oauth-admin-createclient", - "product": "auth", - "slug": "oauth-admin-createclient", - "title": "createClient", - "type": "function", - }, - { - "id": "oauth-admin-deleteclient", - "product": "auth", - "slug": "oauth-admin-deleteclient", - "title": "deleteClient", - "type": "function", - }, - { - "id": "oauth-admin-getclient", - "product": "auth", - "slug": "oauth-admin-getclient", - "title": "getClient", - "type": "function", - }, - { - "id": "oauth-admin-listclients", - "product": "auth", - "slug": "oauth-admin-listclients", - "title": "listClients", - "type": "function", - }, - { - "id": "oauth-admin-regenerateclientsecret", - "product": "auth", - "slug": "oauth-admin-regenerateclientsecret", - "title": "regenerateClientSecret", - "type": "function", - }, - { - "id": "oauth-admin-updateclient", - "product": "auth", - "slug": "oauth-admin-updateclient", - "title": "updateClient", - "type": "function", - }, - { - "id": "oauth-server", - "slug": "oauth-server", - "title": "OAuth Server", - "type": "function", - }, - { - "id": "oauth-server-approveauthorization", - "product": "auth", - "slug": "oauth-server-approveauthorization", - "title": "approveAuthorization", - "type": "function", - }, - { - "id": "oauth-server-denyauthorization", - "product": "auth", - "slug": "oauth-server-denyauthorization", - "title": "denyAuthorization", - "type": "function", - }, - { - "id": "oauth-server-getauthorizationdetails", - "product": "auth", - "slug": "oauth-server-getauthorizationdetails", - "title": "getAuthorizationDetails", - "type": "function", - }, - { - "id": "oauth-server-listgrants", - "product": "auth", - "slug": "oauth-server-listgrants", - "title": "listGrants", - "type": "function", - }, - { - "id": "oauth-server-revokegrant", - "product": "auth", - "slug": "oauth-server-revokegrant", - "title": "revokeGrant", - "type": "function", - }, - { - "id": "passkey-admin", - "slug": "passkey-admin", - "title": "Passkey admin", - "type": "function", - }, - { - "id": "passkey-admin-deletepasskey", - "product": "auth", - "slug": "passkey-admin-deletepasskey", - "title": "deletePasskey", - "type": "function", - }, - { - "id": "passkey-admin-listpasskeys", - "product": "auth", - "slug": "passkey-admin-listpasskeys", - "title": "listPasskeys", - "type": "function", - }, - { - "title": "Edge Functions", - "type": "category", - }, - { - "id": "functions-corsheaders", - "product": "edge-functions", - "slug": "functions-corsheaders", - "title": "corsHeaders", - "type": "function", - }, - { - "id": "functions-invoke", - "product": "edge-functions", - "slug": "functions-invoke", - "title": "invoke", - "type": "function", - }, - { - "id": "functions-setauth", - "product": "edge-functions", - "slug": "functions-setauth", - "title": "setAuth", - "type": "function", - }, - { - "title": "Realtime", - "type": "category", - }, - { - "id": "channel", - "product": "realtime", - "slug": "channel", - "title": "channel", - "type": "function", - }, - { - "id": "connect", - "product": "realtime", - "slug": "connect", - "title": "connect", - "type": "function", - }, - { - "id": "connectionstate", - "product": "realtime", - "slug": "connectionstate", - "title": "connectionState", - "type": "function", - }, - { - "id": "disconnect", - "product": "realtime", - "slug": "disconnect", - "title": "disconnect", - "type": "function", - }, - { - "id": "endpointurl", - "product": "realtime", - "slug": "endpointurl", - "title": "endpointURL", - "type": "function", - }, - { - "id": "getchannels", - "product": "realtime", - "slug": "getchannels", - "title": "getChannels", - "type": "function", - }, - { - "id": "getwebsocketconstructor", - "product": "realtime", - "slug": "getwebsocketconstructor", - "title": "getWebSocketConstructor", - "type": "function", - }, - { - "id": "httpsend", - "product": "realtime", - "slug": "httpsend", - "title": "httpSend", - "type": "function", - }, - { - "id": "isconnected", - "product": "realtime", - "slug": "isconnected", - "title": "isConnected", - "type": "function", - }, - { - "id": "isconnecting", - "product": "realtime", - "slug": "isconnecting", - "title": "isConnecting", - "type": "function", - }, - { - "id": "isdisconnecting", - "product": "realtime", - "slug": "isdisconnecting", - "title": "isDisconnecting", - "type": "function", - }, - { - "id": "iswebsocketsupported", - "product": "realtime", - "slug": "iswebsocketsupported", - "title": "isWebSocketSupported", - "type": "function", - }, - { - "id": "log", - "product": "realtime", - "slug": "log", - "title": "log", - "type": "function", - }, - { - "id": "on", - "product": "realtime", - "slug": "on", - "title": "on", - "type": "function", - }, - { - "id": "onheartbeat", - "product": "realtime", - "slug": "onheartbeat", - "title": "onHeartbeat", - "type": "function", - }, - { - "id": "presencestate", - "product": "realtime", - "slug": "presencestate", - "title": "presenceState", - "type": "function", - }, - { - "id": "push", - "product": "realtime", - "slug": "push", - "title": "push", - "type": "function", - }, - { - "id": "removeallchannels", - "product": "realtime", - "slug": "removeallchannels", - "title": "removeAllChannels", - "type": "function", - }, - { - "id": "removechannel", - "product": "realtime", - "slug": "removechannel", - "title": "removeChannel", - "type": "function", - }, - { - "id": "send", - "product": "realtime", - "slug": "send", - "title": "send", - "type": "function", - }, - { - "id": "sendheartbeat", - "product": "realtime", - "slug": "sendheartbeat", - "title": "sendHeartbeat", - "type": "function", - }, - { - "id": "setauth", - "product": "realtime", - "slug": "setauth", - "title": "setAuth", - "type": "function", - }, - { - "id": "subscribe", - "product": "realtime", - "slug": "subscribe", - "title": "subscribe", - "type": "function", - }, - { - "id": "teardown", - "product": "realtime", - "slug": "teardown", - "title": "teardown", - "type": "function", - }, - { - "id": "track", - "product": "realtime", - "slug": "track", - "title": "track", - "type": "function", - }, - { - "id": "unsubscribe", - "product": "realtime", - "slug": "unsubscribe", - "title": "unsubscribe", - "type": "function", - }, - { - "id": "untrack", - "product": "realtime", - "slug": "untrack", - "title": "untrack", - "type": "function", - }, - { - "id": "updatejoinpayload", - "product": "realtime", - "slug": "updatejoinpayload", - "title": "updateJoinPayload", - "type": "function", - }, - { - "title": "Storage", - "type": "category", - }, - { - "id": "analytics-buckets", - "slug": "analytics-buckets", - "title": "Analytics Buckets", - "type": "function", - }, - { - "id": "analytics-buckets-createbucket", - "product": "storage", - "slug": "analytics-buckets-createbucket", - "title": "createBucket", - "type": "function", - }, - { - "id": "analytics-buckets-deletebucket", - "product": "storage", - "slug": "analytics-buckets-deletebucket", - "title": "deleteBucket", - "type": "function", - }, - { - "id": "analytics-buckets-from", - "product": "storage", - "slug": "analytics-buckets-from", - "title": "from", - "type": "function", - }, - { - "id": "analytics-buckets-listbuckets", - "product": "storage", - "slug": "analytics-buckets-listbuckets", - "title": "listBuckets", - "type": "function", - }, - { - "id": "file-buckets", - "slug": "file-buckets", - "title": "File Buckets", - "type": "function", - }, - { - "id": "file-buckets-copy", - "product": "storage", - "slug": "file-buckets-copy", - "title": "copy", - "type": "function", - }, - { - "id": "file-buckets-createbucket", - "product": "storage", - "slug": "file-buckets-createbucket", - "title": "createBucket", - "type": "function", - }, - { - "id": "file-buckets-createsigneduploadurl", - "product": "storage", - "slug": "file-buckets-createsigneduploadurl", - "title": "createSignedUploadUrl", - "type": "function", - }, - { - "id": "file-buckets-createsignedurl", - "product": "storage", - "slug": "file-buckets-createsignedurl", - "title": "createSignedUrl", - "type": "function", - }, - { - "id": "file-buckets-createsignedurls", - "product": "storage", - "slug": "file-buckets-createsignedurls", - "title": "createSignedUrls", - "type": "function", - }, - { - "id": "file-buckets-deletebucket", - "product": "storage", - "slug": "file-buckets-deletebucket", - "title": "deleteBucket", - "type": "function", - }, - { - "id": "file-buckets-download", - "product": "storage", - "slug": "file-buckets-download", - "title": "download", - "type": "function", - }, - { - "id": "file-buckets-emptybucket", - "product": "storage", - "slug": "file-buckets-emptybucket", - "title": "emptyBucket", - "type": "function", - }, - { - "id": "file-buckets-exists", - "product": "storage", - "slug": "file-buckets-exists", - "title": "exists", - "type": "function", - }, - { - "id": "file-buckets-from", - "product": "storage", - "slug": "file-buckets-from", - "title": "from", - "type": "function", - }, - { - "id": "file-buckets-getbucket", - "product": "storage", - "slug": "file-buckets-getbucket", - "title": "getBucket", - "type": "function", - }, - { - "id": "file-buckets-getpublicurl", - "product": "storage", - "slug": "file-buckets-getpublicurl", - "title": "getPublicUrl", - "type": "function", - }, - { - "id": "file-buckets-info", - "product": "storage", - "slug": "file-buckets-info", - "title": "info", - "type": "function", - }, - { - "id": "file-buckets-list", - "product": "storage", - "slug": "file-buckets-list", - "title": "list", - "type": "function", - }, - { - "id": "file-buckets-listbuckets", - "product": "storage", - "slug": "file-buckets-listbuckets", - "title": "listBuckets", - "type": "function", - }, - { - "id": "file-buckets-listv2", - "product": "storage", - "slug": "file-buckets-listv2", - "title": "listV2", - "type": "function", - }, - { - "id": "file-buckets-move", - "product": "storage", - "slug": "file-buckets-move", - "title": "move", - "type": "function", - }, - { - "id": "file-buckets-remove", - "product": "storage", - "slug": "file-buckets-remove", - "title": "remove", - "type": "function", - }, - { - "id": "file-buckets-update", - "product": "storage", - "slug": "file-buckets-update", - "title": "update", - "type": "function", - }, - { - "id": "file-buckets-updatebucket", - "product": "storage", - "slug": "file-buckets-updatebucket", - "title": "updateBucket", - "type": "function", - }, - { - "id": "file-buckets-upload", - "product": "storage", - "slug": "file-buckets-upload", - "title": "upload", - "type": "function", - }, - { - "id": "file-buckets-uploadtosignedurl", - "product": "storage", - "slug": "file-buckets-uploadtosignedurl", - "title": "uploadToSignedUrl", - "type": "function", - }, - { - "id": "vector-buckets", - "slug": "vector-buckets", - "title": "Vector Buckets", - "type": "function", - }, - { - "id": "vector-buckets-createbucket", - "product": "storage", - "slug": "vector-buckets-createbucket", - "title": "createBucket", - "type": "function", - }, - { - "id": "vector-buckets-createindex", - "product": "storage", - "slug": "vector-buckets-createindex", - "title": "createIndex", - "type": "function", - }, - { - "id": "vector-buckets-deletebucket", - "product": "storage", - "slug": "vector-buckets-deletebucket", - "title": "deleteBucket", - "type": "function", - }, - { - "id": "vector-buckets-deleteindex", - "product": "storage", - "slug": "vector-buckets-deleteindex", - "title": "deleteIndex", - "type": "function", - }, - { - "id": "vector-buckets-deletevectors", - "product": "storage", - "slug": "vector-buckets-deletevectors", - "title": "deleteVectors", - "type": "function", - }, - { - "id": "vector-buckets-from", - "product": "storage", - "slug": "vector-buckets-from", - "title": "from", - "type": "function", - }, - { - "id": "vector-buckets-getbucket", - "product": "storage", - "slug": "vector-buckets-getbucket", - "title": "getBucket", - "type": "function", - }, - { - "id": "vector-buckets-getindex", - "product": "storage", - "slug": "vector-buckets-getindex", - "title": "getIndex", - "type": "function", - }, - { - "id": "vector-buckets-getvectors", - "product": "storage", - "slug": "vector-buckets-getvectors", - "title": "getVectors", - "type": "function", - }, - { - "id": "vector-buckets-index", - "product": "storage", - "slug": "vector-buckets-index", - "title": "index", - "type": "function", - }, - { - "id": "vector-buckets-listbuckets", - "product": "storage", - "slug": "vector-buckets-listbuckets", - "title": "listBuckets", - "type": "function", - }, - { - "id": "vector-buckets-listindexes", - "product": "storage", - "slug": "vector-buckets-listindexes", - "title": "listIndexes", - "type": "function", - }, - { - "id": "vector-buckets-listvectors", - "product": "storage", - "slug": "vector-buckets-listvectors", - "title": "listVectors", - "type": "function", - }, - { - "id": "vector-buckets-putvectors", - "product": "storage", - "slug": "vector-buckets-putvectors", - "title": "putVectors", - "type": "function", - }, - { - "id": "vector-buckets-queryvectors", - "product": "storage", - "slug": "vector-buckets-queryvectors", - "title": "queryVectors", - "type": "function", - }, - ], - "functionsList": [ - { - "$ref": "@supabase/supabase-js.SupabaseClient.constructor", - "id": "initializing", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestQueryBuilder.delete", - "id": "delete", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestClient.from", - "id": "from", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.geojson", - "id": "geojson", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestQueryBuilder.insert", - "id": "insert", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.maxAffected", - "id": "maxaffected", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestBuilder.retry", - "id": "retry", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestBuilder.returns", - "id": "returns", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.rollback", - "id": "rollback", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestClient.rpc", - "id": "rpc", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestClient.schema", - "id": "schema", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestQueryBuilder.select", - "id": "select", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestBuilder.setHeader", - "id": "setheader", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestBuilder.throwOnError", - "id": "throwonerror", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestQueryBuilder.update", - "id": "update", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestQueryBuilder.upsert", - "id": "upsert", - }, - { - "description": "Filters allow you to only return rows that match certain conditions. - -Filters can be used on \`select()\`, \`update()\`, \`upsert()\`, and \`delete()\` queries. - -If a Postgres function returns a table response, you can also apply filters. -", - "examples": [ - { - "code": "\`\`\`ts -const { data, error } = await supabase - .from('instruments') - .select('name, section_id') - .eq('name', 'violin') // Correct - -const { data, error } = await supabase - .from('instruments') - .eq('name', 'violin') // Incorrect - .select('name, section_id') -\`\`\` -", - "description": "Filters must be applied after any of \`select()\`, \`update()\`, \`upsert()\`, -\`delete()\`, and \`rpc()\` and before -[modifiers](/docs/reference/javascript/using-modifiers). -", - "id": "applying-filters", - "name": "Applying Filters", - }, - { - "code": "\`\`\`ts -const { data, error } = await supabase - .from('cities') - .select('name, country_id') - .gte('population', 1000) - .lt('population', 10000) -\`\`\` -", - "description": "Filters can be chained together to produce advanced queries. For example, -to query cities with population between 1,000 and 10,000: - -\`\`\`ts -const { data, error } = await supabase - .from('cities') - .select('name, country_id') - .gte('population', 1000) - .lt('population', 10000) -\`\`\` -", - "id": "chaining-filters", - "name": "Chaining", - }, - { - "code": "\`\`\`ts -const filterByName = null -const filterPopLow = 1000 -const filterPopHigh = 10000 - -let query = supabase - .from('cities') - .select('name, country_id') - -if (filterByName) { query = query.eq('name', filterByName) } -if (filterPopLow) { query = query.gte('population', filterPopLow) } -if (filterPopHigh) { query = query.lt('population', filterPopHigh) } - -const { data, error } = await query -\`\`\` -", - "description": "Filters can be built up one step at a time and then executed. For example: - -\`\`\`ts -const filterByName = null -const filterPopLow = 1000 -const filterPopHigh = 10000 - -let query = supabase - .from('cities') - .select('name, country_id') - -if (filterByName) { query = query.eq('name', filterByName) } -if (filterPopLow) { query = query.gte('population', filterPopLow) } -if (filterPopHigh) { query = query.lt('population', filterPopHigh) } - -const { data, error } = await query -\`\`\` -", - "id": "conditional-chaining", - "name": "Conditional Chaining", - }, - { - "code": "\`\`\`ts -const { data, error } = await supabase - .from('users') - .select() - .eq('address->postcode', 90210) -\`\`\` -", - "data": { - "sql": "\`\`\`sql -create table - users ( - id int8 primary key, - name text, - address jsonb - ); - -insert into - users (id, name, address) -values - (1, 'Michael', '{ "postcode": 90210 }'), - (2, 'Jane', null); -\`\`\` -", - }, - "id": "filter-by-value-within-json-column", - "name": "Filter by values within a JSON column", - "response": "\`\`\`json -{ - "data": [ - { - "id": 1, - "name": "Michael", - "address": { - "postcode": 90210 - } - } - ], - "status": 200, - "statusText": "OK" -} -\`\`\` -", - }, - { - "code": "\`\`\`ts -const { data, error } = await supabase - .from('orchestral_sections') - .select(\` - name, - instruments!inner ( - name - ) - \`) - .eq('instruments.name', 'flute') -\`\`\` -", - "data": { - "response": "\`\`\`json -{ - "data": [ - { - "name": "woodwinds", - "characters": [ - { - "name": "flute" - } - ] - } - ], - "status": 200, - "statusText": "OK" -} -\`\`\` -", - "sql": "\`\`\`sql -create table - orchestral_sections (id int8 primary key, name text); -create table - instruments ( - id int8 primary key, - section_id int8 not null references orchestral_sections, - name text - ); - -insert into - orchestral_sections (id, name) -values - (1, 'strings'), - (2, 'woodwinds'); -insert into - instruments (id, section_id, name) -values - (1, 2, 'flute'), - (2, 1, 'violin'); -\`\`\` -", - }, - "description": "You can filter on referenced tables in your \`select()\` query using dot -notation. -", - "id": "filter-referenced-tables", - "name": "Filter referenced tables", - }, - ], - "id": "using-filters", - "title": "Using Filters", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.containedBy", - "id": "using-filters-containedby", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.contains", - "id": "using-filters-contains", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.eq", - "id": "using-filters-eq", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.filter", - "id": "using-filters-filter", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.gt", - "id": "using-filters-gt", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.gte", - "id": "using-filters-gte", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.ilike", - "id": "using-filters-ilike", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.ilikeAllOf", - "id": "using-filters-ilikeallof", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.ilikeAnyOf", - "id": "using-filters-ilikeanyof", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.in", - "id": "using-filters-in", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.is", - "id": "using-filters-is", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.like", - "id": "using-filters-like", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.likeAllOf", - "id": "using-filters-likeallof", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.likeAnyOf", - "id": "using-filters-likeanyof", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.lt", - "id": "using-filters-lt", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.lte", - "id": "using-filters-lte", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.match", - "id": "using-filters-match", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.neq", - "id": "using-filters-neq", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.not", - "id": "using-filters-not", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.or", - "id": "using-filters-or", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.overlaps", - "id": "using-filters-overlaps", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeAdjacent", - "id": "using-filters-rangeadjacent", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeGt", - "id": "using-filters-rangegt", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeGte", - "id": "using-filters-rangegte", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeLt", - "id": "using-filters-rangelt", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeLte", - "id": "using-filters-rangelte", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.textSearch", - "id": "using-filters-textsearch", - }, - { - "description": "Filters work on the row level—they allow you to return rows that only match certain conditions without changing the shape of the rows. Modifiers are everything that don't fit that definition—allowing you to change the format of the response (e.g., returning a CSV string). - -Modifiers must be specified after filters. Some modifiers only apply for queries that return rows (e.g., \`select()\` or \`rpc()\` on a function that returns a table response).", - "id": "using-modifiers", - "title": "Using modifiers", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.abortSignal", - "id": "using-modifiers-abortsignal", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.csv", - "id": "using-modifiers-csv", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.explain", - "id": "using-modifiers-explain", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.limit", - "id": "using-modifiers-limit", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.maybeSingle", - "id": "using-modifiers-maybesingle", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.order", - "id": "using-modifiers-order", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestBuilder.overrideTypes", - "id": "using-modifiers-overridetypes", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.range", - "id": "using-modifiers-range", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.returns", - "id": "using-modifiers-returns", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.select", - "id": "using-modifiers-select", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.single", - "id": "using-modifiers-single", - }, - { - "$ref": "@supabase/postgrest-js.PostgrestBuilder.stripNulls", - "id": "using-modifiers-stripnulls", - }, - { - "examples": [ - { - "code": "\`\`\`js -import { createClient } from '@supabase/supabase-js' - -const supabase = createClient(supabase_url, publishable_key) -\`\`\` -", - "id": "create-auth-client", - "isSpotlight": true, - "name": "Create auth client", - }, - { - "code": "\`\`\`js -import { createClient } from '@supabase/supabase-js' - -const supabase = createClient(supabase_url, publishable_key, { - auth: { - autoRefreshToken: false, - persistSession: false, - detectSessionInUrl: false - } -}) -\`\`\` -", - "id": "create-auth-client-server-side", - "isSpotlight": false, - "name": "Create auth client (server-side)", - }, - ], - "id": "auth", - "notes": "- The auth methods can be accessed via the \`supabase.auth\` namespace. -- By default, the supabase client sets \`persistSession\` to true and attempts to store the session in local storage. When using the supabase client in an environment that doesn't support local storage, you might notice the following warning message being logged: - - > No storage option exists to persist the session, which may result in unexpected behavior when using auth. If you want to set \`persistSession\` to true, please provide a storage option or you may set \`persistSession\` to false to disable this warning. - - This warning message can be safely ignored if you're not using auth on the server-side. If you are using auth and you want to set \`persistSession\` to true, you will need to provide a custom storage implementation that follows [this interface](https://github.com/supabase/supabase-js/blob/master/packages/core/auth-js/src/lib/types.ts#L1053). -- Any email links and one-time passwords (OTPs) sent have a default expiry of 24 hours. We have the following [rate limits](/docs/guides/platform/going-into-prod#auth-rate-limits) in place to guard against brute force attacks. -- The expiry of an access token can be set in the "JWT expiry limit" field in [your project's auth settings](/dashboard/project/_/auth/providers). A refresh token never expires and can only be used once. -", - "title": "Overview", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.dispose", - "id": "auth-dispose", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.exchangeCodeForSession", - "id": "auth-exchangecodeforsession", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.getClaims", - "id": "auth-getclaims", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.getSession", - "id": "auth-getsession", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.getUser", - "id": "auth-getuser", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.getUserIdentities", - "id": "auth-getuseridentities", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.initialize", - "id": "auth-initialize", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.linkIdentity", - "id": "auth-linkidentity", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.onAuthStateChange", - "id": "auth-onauthstatechange", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.reauthenticate", - "id": "auth-reauthenticate", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.refreshSession", - "id": "auth-refreshsession", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.registerPasskey", - "id": "auth-registerpasskey", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.resend", - "id": "auth-resend", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.resetPasswordForEmail", - "id": "auth-resetpasswordforemail", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.setSession", - "id": "auth-setsession", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.signInAnonymously", - "id": "auth-signinanonymously", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.signInWithIdToken", - "id": "auth-signinwithidtoken", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.signInWithOAuth", - "id": "auth-signinwithoauth", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.signInWithOtp", - "id": "auth-signinwithotp", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.signInWithPasskey", - "id": "auth-signinwithpasskey", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.signInWithPassword", - "id": "auth-signinwithpassword", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.signInWithSSO", - "id": "auth-signinwithsso", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.signInWithWeb3", - "id": "auth-signinwithweb3", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.signOut", - "id": "auth-signout", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.signUp", - "id": "auth-signup", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.startAutoRefresh", - "id": "auth-startautorefresh", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.stopAutoRefresh", - "id": "auth-stopautorefresh", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.unlinkIdentity", - "id": "auth-unlinkidentity", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.updateUser", - "id": "auth-updateuser", - }, - { - "$ref": "@supabase/auth-js.GoTrueClient.verifyOtp", - "id": "auth-verifyotp", - }, - { - "examples": [ - { - "code": "\`\`\`js -import { createClient } from '@supabase/supabase-js' - -const supabase = createClient(supabase_url, secret_key, { - auth: { - autoRefreshToken: false, - persistSession: false - } -}) - -// Access auth admin api -const adminAuthClient = supabase.auth.admin -\`\`\` -", - "id": "create-auth-admin-client", - "isSpotlight": true, - "name": "Create server-side auth client", - }, - ], - "id": "auth-admin", - "notes": "- Any method under the \`supabase.auth.admin\` namespace requires a \`secret\` key. -- These methods are considered admin methods and should be called on a trusted server. Never expose your \`secret\` key in the browser. -", - "title": "Overview", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.createProvider", - "id": "auth-admin-createprovider", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminApi.createUser", - "id": "auth-admin-createuser", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminMFAApi.deleteFactor", - "id": "auth-admin-deletefactor", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.deleteProvider", - "id": "auth-admin-deleteprovider", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminApi.deleteUser", - "id": "auth-admin-deleteuser", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminApi.generateLink", - "id": "auth-admin-generatelink", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.getProvider", - "id": "auth-admin-getprovider", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminApi.getUserById", - "id": "auth-admin-getuserbyid", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminApi.inviteUserByEmail", - "id": "auth-admin-inviteuserbyemail", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminMFAApi.listFactors", - "id": "auth-admin-listfactors", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.listProviders", - "id": "auth-admin-listproviders", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminApi.listUsers", - "id": "auth-admin-listusers", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminApi.signOut", - "id": "auth-admin-signout", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.updateProvider", - "id": "auth-admin-updateprovider", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminApi.updateUserById", - "id": "auth-admin-updateuserbyid", - }, - { - "description": "This section contains methods commonly used for Multi-Factor Authentication (MFA) and are invoked behind the \`supabase.auth.mfa\` namespace. - -Currently, there is support for time-based one-time password (TOTP) and phone verification code as the 2nd factor. Recovery codes are not supported but users can enroll multiple factors, with an upper limit of 10. - -Having a 2nd factor for recovery frees the user of the burden of having to store their recovery codes somewhere. It also reduces the attack surface since multiple recovery codes are usually generated compared to just having 1 backup factor. - -Learn more about implementing MFA in your application [in the MFA guide](https://supabase.com/docs/guides/auth/auth-mfa#overview).", - "id": "auth-mfa", - "title": "Auth MFA", - }, - { - "$ref": "@supabase/auth-js.GoTrueMFAApi.challenge", - "id": "auth-mfa-challenge", - }, - { - "$ref": "@supabase/auth-js.GoTrueMFAApi.challengeAndVerify", - "id": "auth-mfa-challengeandverify", - }, - { - "$ref": "@supabase/auth-js.GoTrueMFAApi.enroll", - "id": "auth-mfa-enroll", - }, - { - "$ref": "@supabase/auth-js.GoTrueMFAApi.getAuthenticatorAssuranceLevel", - "id": "auth-mfa-getauthenticatorassurancelevel", - }, - { - "$ref": "@supabase/auth-js.GoTrueMFAApi.listFactors", - "id": "auth-mfa-listfactors", - }, - { - "$ref": "@supabase/auth-js.GoTrueMFAApi.unenroll", - "id": "auth-mfa-unenroll", - }, - { - "$ref": "@supabase/auth-js.GoTrueMFAApi.verify", - "id": "auth-mfa-verify", - }, - { - "code": "\`\`\`js -const supabase = createClient(supabaseUrl, publishableKey, { - auth: { - experimental: { passkey: true }, - }, -}) -\`\`\`", - "description": "This section contains methods for WebAuthn passkey registration, authentication, and management. Methods are invoked behind the \`supabase.auth.passkey\` namespace. - -Passkey support is an experimental feature. Enable it when creating the client:", - "id": "auth-passkey", - "title": "Auth Passkey", - }, - { - "$ref": "@supabase/auth-js.AuthPasskeyApi.delete", - "id": "auth-passkey-delete", - }, - { - "$ref": "@supabase/auth-js.AuthPasskeyApi.list", - "id": "auth-passkey-list", - }, - { - "$ref": "@supabase/auth-js.AuthPasskeyApi.startAuthentication", - "id": "auth-passkey-startauthentication", - }, - { - "$ref": "@supabase/auth-js.AuthPasskeyApi.startRegistration", - "id": "auth-passkey-startregistration", - }, - { - "$ref": "@supabase/auth-js.AuthPasskeyApi.update", - "id": "auth-passkey-update", - }, - { - "$ref": "@supabase/auth-js.AuthPasskeyApi.verifyAuthentication", - "id": "auth-passkey-verifyauthentication", - }, - { - "$ref": "@supabase/auth-js.AuthPasskeyApi.verifyRegistration", - "id": "auth-passkey-verifyregistration", - }, - { - "description": "The OAuth Admin API allows you to manage OAuth clients programmatically. Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. These functions should only be called on a server. Never expose your \`secret\` key in the browser.", - "id": "oauth-admin", - "title": "OAuth Admin", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminOAuthApi.createClient", - "id": "oauth-admin-createclient", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminOAuthApi.deleteClient", - "id": "oauth-admin-deleteclient", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminOAuthApi.getClient", - "id": "oauth-admin-getclient", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminOAuthApi.listClients", - "id": "oauth-admin-listclients", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminOAuthApi.regenerateClientSecret", - "id": "oauth-admin-regenerateclientsecret", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminOAuthApi.updateClient", - "id": "oauth-admin-updateclient", - }, - { - "description": "The OAuth Server API allows you to build custom OAuth consent screens for your application. Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.", - "id": "oauth-server", - "title": "OAuth Server", - }, - { - "$ref": "@supabase/auth-js.AuthOAuthServerApi.approveAuthorization", - "id": "oauth-server-approveauthorization", - }, - { - "$ref": "@supabase/auth-js.AuthOAuthServerApi.denyAuthorization", - "id": "oauth-server-denyauthorization", - }, - { - "$ref": "@supabase/auth-js.AuthOAuthServerApi.getAuthorizationDetails", - "id": "oauth-server-getauthorizationdetails", - }, - { - "$ref": "@supabase/auth-js.AuthOAuthServerApi.listGrants", - "id": "oauth-server-listgrants", - }, - { - "$ref": "@supabase/auth-js.AuthOAuthServerApi.revokeGrant", - "id": "oauth-server-revokegrant", - }, - { - "description": "Contains passkey administration methods. Requires a secret key.", - "id": "passkey-admin", - "title": "Passkey admin", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminPasskeyApi.deletePasskey", - "id": "passkey-admin-deletepasskey", - }, - { - "$ref": "@supabase/auth-js.GoTrueAdminPasskeyApi.listPasskeys", - "id": "passkey-admin-listpasskeys", - }, - { - "$ref": "@supabase/supabase-js.cors.corsHeaders", - "id": "functions-corsheaders", - }, - { - "$ref": "@supabase/functions-js.FunctionsClient.invoke", - "id": "functions-invoke", - }, - { - "$ref": "@supabase/functions-js.FunctionsClient.setAuth", - "id": "functions-setauth", - }, - { - "$ref": "@supabase/realtime-js.RealtimeClient.channel", - "id": "channel", - }, - { - "$ref": "@supabase/realtime-js.RealtimeClient.connect", - "id": "connect", - }, - { - "$ref": "@supabase/realtime-js.RealtimeClient.connectionState", - "id": "connectionstate", - }, - { - "$ref": "@supabase/realtime-js.RealtimeClient.disconnect", - "id": "disconnect", - }, - { - "$ref": "@supabase/realtime-js.RealtimeClient.endpointURL", - "id": "endpointurl", - }, - { - "$ref": "@supabase/realtime-js.RealtimeClient.getChannels", - "id": "getchannels", - }, - { - "$ref": "@supabase/realtime-js.WebSocketFactory.getWebSocketConstructor", - "id": "getwebsocketconstructor", - }, - { - "$ref": "@supabase/realtime-js.RealtimeChannel.httpSend", - "id": "httpsend", - }, - { - "$ref": "@supabase/realtime-js.RealtimeClient.isConnected", - "id": "isconnected", - }, - { - "$ref": "@supabase/realtime-js.RealtimeClient.isConnecting", - "id": "isconnecting", - }, - { - "$ref": "@supabase/realtime-js.RealtimeClient.isDisconnecting", - "id": "isdisconnecting", - }, - { - "$ref": "@supabase/realtime-js.WebSocketFactory.isWebSocketSupported", - "id": "iswebsocketsupported", - }, - { - "$ref": "@supabase/realtime-js.RealtimeClient.log", - "id": "log", - }, - { - "$ref": "@supabase/realtime-js.RealtimeChannel.on", - "id": "on", - }, - { - "$ref": "@supabase/realtime-js.RealtimeClient.onHeartbeat", - "id": "onheartbeat", - }, - { - "$ref": "@supabase/realtime-js.RealtimeChannel.presenceState", - "id": "presencestate", - }, - { - "$ref": "@supabase/realtime-js.RealtimeClient.push", - "id": "push", - }, - { - "$ref": "@supabase/realtime-js.RealtimeClient.removeAllChannels", - "id": "removeallchannels", - }, - { - "$ref": "@supabase/realtime-js.RealtimeClient.removeChannel", - "id": "removechannel", - }, - { - "$ref": "@supabase/realtime-js.RealtimeChannel.send", - "id": "send", - }, - { - "$ref": "@supabase/realtime-js.RealtimeClient.sendHeartbeat", - "id": "sendheartbeat", - }, - { - "$ref": "@supabase/realtime-js.RealtimeClient.setAuth", - "id": "setauth", - }, - { - "$ref": "@supabase/realtime-js.RealtimeChannel.subscribe", - "id": "subscribe", - }, - { - "$ref": "@supabase/realtime-js.RealtimeChannel.teardown", - "id": "teardown", - }, - { - "$ref": "@supabase/realtime-js.RealtimeChannel.track", - "id": "track", - }, - { - "$ref": "@supabase/realtime-js.RealtimeChannel.unsubscribe", - "id": "unsubscribe", - }, - { - "$ref": "@supabase/realtime-js.RealtimeChannel.untrack", - "id": "untrack", - }, - { - "$ref": "@supabase/realtime-js.RealtimeChannel.updateJoinPayload", - "id": "updatejoinpayload", - }, - { - "description": "This section contains methods for working with Analytics Buckets.", - "id": "analytics-buckets", - "title": "Analytics Buckets", - }, - { - "$ref": "@supabase/storage-js.packages/StorageAnalyticsClient.default.createBucket", - "id": "analytics-buckets-createbucket", - }, - { - "$ref": "@supabase/storage-js.packages/StorageAnalyticsClient.default.deleteBucket", - "id": "analytics-buckets-deletebucket", - }, - { - "$ref": "@supabase/storage-js.packages/StorageAnalyticsClient.default.from", - "id": "analytics-buckets-from", - }, - { - "$ref": "@supabase/storage-js.packages/StorageAnalyticsClient.default.listBuckets", - "id": "analytics-buckets-listbuckets", - }, - { - "description": "This section contains methods for working with File Buckets.", - "id": "file-buckets", - "title": "File Buckets", - }, - { - "$ref": "@supabase/storage-js.packages/StorageFileApi.default.copy", - "id": "file-buckets-copy", - }, - { - "$ref": "@supabase/storage-js.StorageClient.createBucket", - "id": "file-buckets-createbucket", - }, - { - "$ref": "@supabase/storage-js.packages/StorageFileApi.default.createSignedUploadUrl", - "id": "file-buckets-createsigneduploadurl", - }, - { - "$ref": "@supabase/storage-js.packages/StorageFileApi.default.createSignedUrl", - "id": "file-buckets-createsignedurl", - }, - { - "$ref": "@supabase/storage-js.packages/StorageFileApi.default.createSignedUrls", - "id": "file-buckets-createsignedurls", - }, - { - "$ref": "@supabase/storage-js.StorageClient.deleteBucket", - "id": "file-buckets-deletebucket", - }, - { - "$ref": "@supabase/storage-js.packages/StorageFileApi.default.download", - "id": "file-buckets-download", - }, - { - "$ref": "@supabase/storage-js.StorageClient.emptyBucket", - "id": "file-buckets-emptybucket", - }, - { - "$ref": "@supabase/storage-js.packages/StorageFileApi.default.exists", - "id": "file-buckets-exists", - }, - { - "$ref": "@supabase/storage-js.StorageClient.from", - "id": "file-buckets-from", - }, - { - "$ref": "@supabase/storage-js.StorageClient.getBucket", - "id": "file-buckets-getbucket", - }, - { - "$ref": "@supabase/storage-js.packages/StorageFileApi.default.getPublicUrl", - "id": "file-buckets-getpublicurl", - }, - { - "$ref": "@supabase/storage-js.packages/StorageFileApi.default.info", - "id": "file-buckets-info", - }, - { - "$ref": "@supabase/storage-js.packages/StorageFileApi.default.list", - "id": "file-buckets-list", - }, - { - "$ref": "@supabase/storage-js.StorageClient.listBuckets", - "id": "file-buckets-listbuckets", - }, - { - "$ref": "@supabase/storage-js.packages/StorageFileApi.default.listV2", - "id": "file-buckets-listv2", - }, - { - "$ref": "@supabase/storage-js.packages/StorageFileApi.default.move", - "id": "file-buckets-move", - }, - { - "$ref": "@supabase/storage-js.packages/StorageFileApi.default.remove", - "id": "file-buckets-remove", - }, - { - "$ref": "@supabase/storage-js.packages/StorageFileApi.default.update", - "id": "file-buckets-update", - }, - { - "$ref": "@supabase/storage-js.StorageClient.updateBucket", - "id": "file-buckets-updatebucket", - }, - { - "$ref": "@supabase/storage-js.packages/StorageFileApi.default.upload", - "id": "file-buckets-upload", - }, - { - "$ref": "@supabase/storage-js.packages/StorageFileApi.default.uploadToSignedUrl", - "id": "file-buckets-uploadtosignedurl", - }, - { - "description": "This section contains methods for working with Vector Buckets.", - "id": "vector-buckets", - "title": "Vector Buckets", - }, - { - "$ref": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.createBucket", - "id": "vector-buckets-createbucket", - }, - { - "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.createIndex", - "id": "vector-buckets-createindex", - }, - { - "$ref": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.deleteBucket", - "id": "vector-buckets-deletebucket", - }, - { - "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.deleteIndex", - "id": "vector-buckets-deleteindex", - }, - { - "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.deleteVectors", - "id": "vector-buckets-deletevectors", - }, - { - "$ref": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.from", - "id": "vector-buckets-from", - }, - { - "$ref": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.getBucket", - "id": "vector-buckets-getbucket", - }, - { - "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.getIndex", - "id": "vector-buckets-getindex", - }, - { - "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.getVectors", - "id": "vector-buckets-getvectors", - }, - { - "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope", - "id": "vector-buckets-index", - }, - { - "$ref": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.listBuckets", - "id": "vector-buckets-listbuckets", - }, - { - "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.listIndexes", - "id": "vector-buckets-listindexes", - }, - { - "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.listVectors", - "id": "vector-buckets-listvectors", - }, - { - "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.putVectors", - "id": "vector-buckets-putvectors", - }, - { - "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.queryVectors", - "id": "vector-buckets-queryvectors", - }, - ], - "sections": [ - { - "id": "introduction", - "slug": "introduction", - "title": "Introduction", - "type": "markdown", - }, - { - "id": "installing", - "slug": "installing", - "title": "Installing", - "type": "markdown", - }, - { - "id": "initializing", - "slug": "initializing", - "title": "Initializing", - "type": "function", - }, - { - "id": "typescript-support", - "slug": "typescript-support", - "title": "TypeScript support", - "type": "markdown", - }, - { - "items": [ - { - "id": "delete", - "product": "database", - "slug": "delete", - "title": "delete", - "type": "function", - }, - { - "id": "from", - "product": "database", - "slug": "from", - "title": "from", - "type": "function", - }, - { - "id": "geojson", - "product": "database", - "slug": "geojson", - "title": "geojson", - "type": "function", - }, - { - "id": "insert", - "product": "database", - "slug": "insert", - "title": "insert", - "type": "function", - }, - { - "id": "maxaffected", - "product": "database", - "slug": "maxaffected", - "title": "maxAffected", - "type": "function", - }, - { - "id": "retry", - "product": "database", - "slug": "retry", - "title": "retry", - "type": "function", - }, - { - "id": "returns", - "product": "database", - "slug": "returns", - "title": "returns", - "type": "function", - }, - { - "id": "rollback", - "product": "database", - "slug": "rollback", - "title": "rollback", - "type": "function", - }, - { - "id": "rpc", - "product": "database", - "slug": "rpc", - "title": "rpc", - "type": "function", - }, - { - "id": "schema", - "product": "database", - "slug": "schema", - "title": "schema", - "type": "function", - }, - { - "id": "select", - "product": "database", - "slug": "select", - "title": "select", - "type": "function", - }, - { - "id": "setheader", - "product": "database", - "slug": "setheader", - "title": "setHeader", - "type": "function", - }, - { - "id": "throwonerror", - "product": "database", - "slug": "throwonerror", - "title": "throwOnError", - "type": "function", - }, - { - "id": "update", - "product": "database", - "slug": "update", - "title": "update", - "type": "function", - }, - { - "id": "upsert", - "product": "database", - "slug": "upsert", - "title": "upsert", - "type": "function", - }, - { - "id": "using-filters", - "isFunc": false, - "items": [ - { - "id": "using-filters", - "slug": "using-filters", - "title": "Using Filters", - "type": "function", - }, - { - "id": "using-filters-containedby", - "product": "database", - "slug": "using-filters-containedby", - "title": "containedBy", - "type": "function", - }, - { - "id": "using-filters-contains", - "product": "database", - "slug": "using-filters-contains", - "title": "contains", - "type": "function", - }, - { - "id": "using-filters-eq", - "product": "database", - "slug": "using-filters-eq", - "title": "eq", - "type": "function", - }, - { - "id": "using-filters-filter", - "product": "database", - "slug": "using-filters-filter", - "title": "filter", - "type": "function", - }, - { - "id": "using-filters-gt", - "product": "database", - "slug": "using-filters-gt", - "title": "gt", - "type": "function", - }, - { - "id": "using-filters-gte", - "product": "database", - "slug": "using-filters-gte", - "title": "gte", - "type": "function", - }, - { - "id": "using-filters-ilike", - "product": "database", - "slug": "using-filters-ilike", - "title": "ilike", - "type": "function", - }, - { - "id": "using-filters-ilikeallof", - "product": "database", - "slug": "using-filters-ilikeallof", - "title": "ilikeAllOf", - "type": "function", - }, - { - "id": "using-filters-ilikeanyof", - "product": "database", - "slug": "using-filters-ilikeanyof", - "title": "ilikeAnyOf", - "type": "function", - }, - { - "id": "using-filters-in", - "product": "database", - "slug": "using-filters-in", - "title": "in", - "type": "function", - }, - { - "id": "using-filters-is", - "product": "database", - "slug": "using-filters-is", - "title": "is", - "type": "function", - }, - { - "id": "using-filters-like", - "product": "database", - "slug": "using-filters-like", - "title": "like", - "type": "function", - }, - { - "id": "using-filters-likeallof", - "product": "database", - "slug": "using-filters-likeallof", - "title": "likeAllOf", - "type": "function", - }, - { - "id": "using-filters-likeanyof", - "product": "database", - "slug": "using-filters-likeanyof", - "title": "likeAnyOf", - "type": "function", - }, - { - "id": "using-filters-lt", - "product": "database", - "slug": "using-filters-lt", - "title": "lt", - "type": "function", - }, - { - "id": "using-filters-lte", - "product": "database", - "slug": "using-filters-lte", - "title": "lte", - "type": "function", - }, - { - "id": "using-filters-match", - "product": "database", - "slug": "using-filters-match", - "title": "match", - "type": "function", - }, - { - "id": "using-filters-neq", - "product": "database", - "slug": "using-filters-neq", - "title": "neq", - "type": "function", - }, - { - "id": "using-filters-not", - "product": "database", - "slug": "using-filters-not", - "title": "not", - "type": "function", - }, - { - "id": "using-filters-or", - "product": "database", - "slug": "using-filters-or", - "title": "or", - "type": "function", - }, - { - "id": "using-filters-overlaps", - "product": "database", - "slug": "using-filters-overlaps", - "title": "overlaps", - "type": "function", - }, - { - "id": "using-filters-rangeadjacent", - "product": "database", - "slug": "using-filters-rangeadjacent", - "title": "rangeAdjacent", - "type": "function", - }, - { - "id": "using-filters-rangegt", - "product": "database", - "slug": "using-filters-rangegt", - "title": "rangeGt", - "type": "function", - }, - { - "id": "using-filters-rangegte", - "product": "database", - "slug": "using-filters-rangegte", - "title": "rangeGte", - "type": "function", - }, - { - "id": "using-filters-rangelt", - "product": "database", - "slug": "using-filters-rangelt", - "title": "rangeLt", - "type": "function", - }, - { - "id": "using-filters-rangelte", - "product": "database", - "slug": "using-filters-rangelte", - "title": "rangeLte", - "type": "function", - }, - { - "id": "using-filters-textsearch", - "product": "database", - "slug": "using-filters-textsearch", - "title": "textSearch", - "type": "function", - }, - ], - "product": "database", - "slug": "using-filters", - "title": "Using filters", - "type": "function", - }, - { - "id": "using-modifiers", - "isFunc": false, - "items": [ - { - "id": "using-modifiers", - "slug": "using-modifiers", - "title": "Using modifiers", - "type": "function", - }, - { - "id": "using-modifiers-abortsignal", - "product": "database", - "slug": "using-modifiers-abortsignal", - "title": "abortSignal", - "type": "function", - }, - { - "id": "using-modifiers-csv", - "product": "database", - "slug": "using-modifiers-csv", - "title": "csv", - "type": "function", - }, - { - "id": "using-modifiers-explain", - "product": "database", - "slug": "using-modifiers-explain", - "title": "explain", - "type": "function", - }, - { - "id": "using-modifiers-limit", - "product": "database", - "slug": "using-modifiers-limit", - "title": "limit", - "type": "function", - }, - { - "id": "using-modifiers-maybesingle", - "product": "database", - "slug": "using-modifiers-maybesingle", - "title": "maybeSingle", - "type": "function", - }, - { - "id": "using-modifiers-order", - "product": "database", - "slug": "using-modifiers-order", - "title": "order", - "type": "function", - }, - { - "id": "using-modifiers-overridetypes", - "product": "database", - "slug": "using-modifiers-overridetypes", - "title": "overrideTypes", - "type": "function", - }, - { - "id": "using-modifiers-range", - "product": "database", - "slug": "using-modifiers-range", - "title": "range", - "type": "function", - }, - { - "id": "using-modifiers-returns", - "product": "database", - "slug": "using-modifiers-returns", - "title": "returns", - "type": "function", - }, - { - "id": "using-modifiers-select", - "product": "database", - "slug": "using-modifiers-select", - "title": "select", - "type": "function", - }, - { - "id": "using-modifiers-single", - "product": "database", - "slug": "using-modifiers-single", - "title": "single", - "type": "function", - }, - { - "id": "using-modifiers-stripnulls", - "product": "database", - "slug": "using-modifiers-stripnulls", - "title": "stripNulls", - "type": "function", - }, - ], - "product": "database", - "slug": "using-modifiers", - "title": "Using modifiers", - "type": "function", - }, - ], - "title": "Database", - "type": "category", - }, - { - "items": [ - { - "id": "auth", - "slug": "auth", - "title": "Overview", - "type": "function", - }, - { - "id": "auth-dispose", - "product": "auth", - "slug": "auth-dispose", - "title": "dispose", - "type": "function", - }, - { - "id": "auth-exchangecodeforsession", - "product": "auth", - "slug": "auth-exchangecodeforsession", - "title": "exchangeCodeForSession", - "type": "function", - }, - { - "id": "auth-getclaims", - "product": "auth", - "slug": "auth-getclaims", - "title": "getClaims", - "type": "function", - }, - { - "id": "auth-getsession", - "product": "auth", - "slug": "auth-getsession", - "title": "getSession", - "type": "function", - }, - { - "id": "auth-getuser", - "product": "auth", - "slug": "auth-getuser", - "title": "getUser", - "type": "function", - }, - { - "id": "auth-getuseridentities", - "product": "auth", - "slug": "auth-getuseridentities", - "title": "getUserIdentities", - "type": "function", - }, - { - "id": "auth-initialize", - "product": "auth", - "slug": "auth-initialize", - "title": "initialize", - "type": "function", - }, - { - "id": "auth-linkidentity", - "product": "auth", - "slug": "auth-linkidentity", - "title": "linkIdentity", - "type": "function", - }, - { - "id": "auth-onauthstatechange", - "product": "auth", - "slug": "auth-onauthstatechange", - "title": "onAuthStateChange", - "type": "function", - }, - { - "id": "auth-reauthenticate", - "product": "auth", - "slug": "auth-reauthenticate", - "title": "reauthenticate", - "type": "function", - }, - { - "id": "auth-refreshsession", - "product": "auth", - "slug": "auth-refreshsession", - "title": "refreshSession", - "type": "function", - }, - { - "id": "auth-registerpasskey", - "product": "auth", - "slug": "auth-registerpasskey", - "title": "registerPasskey", - "type": "function", - }, - { - "id": "auth-resend", - "product": "auth", - "slug": "auth-resend", - "title": "resend", - "type": "function", - }, - { - "id": "auth-resetpasswordforemail", - "product": "auth", - "slug": "auth-resetpasswordforemail", - "title": "resetPasswordForEmail", - "type": "function", - }, - { - "id": "auth-setsession", - "product": "auth", - "slug": "auth-setsession", - "title": "setSession", - "type": "function", - }, - { - "id": "auth-signinanonymously", - "product": "auth", - "slug": "auth-signinanonymously", - "title": "signInAnonymously", - "type": "function", - }, - { - "id": "auth-signinwithidtoken", - "product": "auth", - "slug": "auth-signinwithidtoken", - "title": "signInWithIdToken", - "type": "function", - }, - { - "id": "auth-signinwithoauth", - "product": "auth", - "slug": "auth-signinwithoauth", - "title": "signInWithOAuth", - "type": "function", - }, - { - "id": "auth-signinwithotp", - "product": "auth", - "slug": "auth-signinwithotp", - "title": "signInWithOtp", - "type": "function", - }, - { - "id": "auth-signinwithpasskey", - "product": "auth", - "slug": "auth-signinwithpasskey", - "title": "signInWithPasskey", - "type": "function", - }, - { - "id": "auth-signinwithpassword", - "product": "auth", - "slug": "auth-signinwithpassword", - "title": "signInWithPassword", - "type": "function", - }, - { - "id": "auth-signinwithsso", - "product": "auth", - "slug": "auth-signinwithsso", - "title": "signInWithSSO", - "type": "function", - }, - { - "id": "auth-signinwithweb3", - "product": "auth", - "slug": "auth-signinwithweb3", - "title": "signInWithWeb3", - "type": "function", - }, - { - "id": "auth-signout", - "product": "auth", - "slug": "auth-signout", - "title": "signOut", - "type": "function", - }, - { - "id": "auth-signup", - "product": "auth", - "slug": "auth-signup", - "title": "signUp", - "type": "function", - }, - { - "id": "auth-startautorefresh", - "product": "auth", - "slug": "auth-startautorefresh", - "title": "startAutoRefresh", - "type": "function", - }, - { - "id": "auth-stopautorefresh", - "product": "auth", - "slug": "auth-stopautorefresh", - "title": "stopAutoRefresh", - "type": "function", - }, - { - "id": "auth-unlinkidentity", - "product": "auth", - "slug": "auth-unlinkidentity", - "title": "unlinkIdentity", - "type": "function", - }, - { - "id": "auth-updateuser", - "product": "auth", - "slug": "auth-updateuser", - "title": "updateUser", - "type": "function", - }, - { - "id": "auth-verifyotp", - "product": "auth", - "slug": "auth-verifyotp", - "title": "verifyOtp", - "type": "function", - }, - { - "id": "auth-admin", - "isFunc": false, - "items": [ - { - "id": "auth-admin", - "slug": "auth-admin", - "title": "Overview", - "type": "function", - }, - { - "id": "auth-admin-createprovider", - "product": "auth", - "slug": "auth-admin-createprovider", - "title": "createProvider", - "type": "function", - }, - { - "id": "auth-admin-createuser", - "product": "auth", - "slug": "auth-admin-createuser", - "title": "createUser", - "type": "function", - }, - { - "id": "auth-admin-deletefactor", - "product": "auth", - "slug": "auth-admin-deletefactor", - "title": "deleteFactor", - "type": "function", - }, - { - "id": "auth-admin-deleteprovider", - "product": "auth", - "slug": "auth-admin-deleteprovider", - "title": "deleteProvider", - "type": "function", - }, - { - "id": "auth-admin-deleteuser", - "product": "auth", - "slug": "auth-admin-deleteuser", - "title": "deleteUser", - "type": "function", - }, - { - "id": "auth-admin-generatelink", - "product": "auth", - "slug": "auth-admin-generatelink", - "title": "generateLink", - "type": "function", - }, - { - "id": "auth-admin-getprovider", - "product": "auth", - "slug": "auth-admin-getprovider", - "title": "getProvider", - "type": "function", - }, - { - "id": "auth-admin-getuserbyid", - "product": "auth", - "slug": "auth-admin-getuserbyid", - "title": "getUserById", - "type": "function", - }, - { - "id": "auth-admin-inviteuserbyemail", - "product": "auth", - "slug": "auth-admin-inviteuserbyemail", - "title": "inviteUserByEmail", - "type": "function", - }, - { - "id": "auth-admin-listfactors", - "product": "auth", - "slug": "auth-admin-listfactors", - "title": "listFactors", - "type": "function", - }, - { - "id": "auth-admin-listproviders", - "product": "auth", - "slug": "auth-admin-listproviders", - "title": "listProviders", - "type": "function", - }, - { - "id": "auth-admin-listusers", - "product": "auth", - "slug": "auth-admin-listusers", - "title": "listUsers", - "type": "function", - }, - { - "id": "auth-admin-signout", - "product": "auth", - "slug": "auth-admin-signout", - "title": "signOut", - "type": "function", - }, - { - "id": "auth-admin-updateprovider", - "product": "auth", - "slug": "auth-admin-updateprovider", - "title": "updateProvider", - "type": "function", - }, - { - "id": "auth-admin-updateuserbyid", - "product": "auth", - "slug": "auth-admin-updateuserbyid", - "title": "updateUserById", - "type": "function", - }, - ], - "product": "auth", - "slug": "auth-admin", - "title": "Auth Admin", - "type": "function", - }, - { - "id": "auth-mfa", - "isFunc": false, - "items": [ - { - "id": "auth-mfa", - "slug": "auth-mfa", - "title": "Auth MFA", - "type": "function", - }, - { - "id": "auth-mfa-challenge", - "product": "auth", - "slug": "auth-mfa-challenge", - "title": "challenge", - "type": "function", - }, - { - "id": "auth-mfa-challengeandverify", - "product": "auth", - "slug": "auth-mfa-challengeandverify", - "title": "challengeAndVerify", - "type": "function", - }, - { - "id": "auth-mfa-enroll", - "product": "auth", - "slug": "auth-mfa-enroll", - "title": "enroll", - "type": "function", - }, - { - "id": "auth-mfa-getauthenticatorassurancelevel", - "product": "auth", - "slug": "auth-mfa-getauthenticatorassurancelevel", - "title": "getAuthenticatorAssuranceLevel", - "type": "function", - }, - { - "id": "auth-mfa-listfactors", - "product": "auth", - "slug": "auth-mfa-listfactors", - "title": "listFactors", - "type": "function", - }, - { - "id": "auth-mfa-unenroll", - "product": "auth", - "slug": "auth-mfa-unenroll", - "title": "unenroll", - "type": "function", - }, - { - "id": "auth-mfa-verify", - "product": "auth", - "slug": "auth-mfa-verify", - "title": "verify", - "type": "function", - }, - ], - "product": "auth", - "slug": "auth-mfa", - "title": "Auth MFA", - "type": "function", - }, - { - "id": "auth-passkey", - "isFunc": false, - "items": [ - { - "id": "auth-passkey", - "slug": "auth-passkey", - "title": "Auth Passkey", - "type": "function", - }, - { - "id": "auth-passkey-delete", - "product": "auth", - "slug": "auth-passkey-delete", - "title": "delete", - "type": "function", - }, - { - "id": "auth-passkey-list", - "product": "auth", - "slug": "auth-passkey-list", - "title": "list", - "type": "function", - }, - { - "id": "auth-passkey-startauthentication", - "product": "auth", - "slug": "auth-passkey-startauthentication", - "title": "startAuthentication", - "type": "function", - }, - { - "id": "auth-passkey-startregistration", - "product": "auth", - "slug": "auth-passkey-startregistration", - "title": "startRegistration", - "type": "function", - }, - { - "id": "auth-passkey-update", - "product": "auth", - "slug": "auth-passkey-update", - "title": "update", - "type": "function", - }, - { - "id": "auth-passkey-verifyauthentication", - "product": "auth", - "slug": "auth-passkey-verifyauthentication", - "title": "verifyAuthentication", - "type": "function", - }, - { - "id": "auth-passkey-verifyregistration", - "product": "auth", - "slug": "auth-passkey-verifyregistration", - "title": "verifyRegistration", - "type": "function", - }, - ], - "product": "auth", - "slug": "auth-passkey", - "title": "Auth Passkey", - "type": "function", - }, - { - "id": "oauth-admin", - "isFunc": false, - "items": [ - { - "id": "oauth-admin", - "slug": "oauth-admin", - "title": "OAuth Admin", - "type": "function", - }, - { - "id": "oauth-admin-createclient", - "product": "auth", - "slug": "oauth-admin-createclient", - "title": "createClient", - "type": "function", - }, - { - "id": "oauth-admin-deleteclient", - "product": "auth", - "slug": "oauth-admin-deleteclient", - "title": "deleteClient", - "type": "function", - }, - { - "id": "oauth-admin-getclient", - "product": "auth", - "slug": "oauth-admin-getclient", - "title": "getClient", - "type": "function", - }, - { - "id": "oauth-admin-listclients", - "product": "auth", - "slug": "oauth-admin-listclients", - "title": "listClients", - "type": "function", - }, - { - "id": "oauth-admin-regenerateclientsecret", - "product": "auth", - "slug": "oauth-admin-regenerateclientsecret", - "title": "regenerateClientSecret", - "type": "function", - }, - { - "id": "oauth-admin-updateclient", - "product": "auth", - "slug": "oauth-admin-updateclient", - "title": "updateClient", - "type": "function", - }, - ], - "product": "auth", - "slug": "oauth-admin", - "title": "OAuth Admin", - "type": "function", - }, - { - "id": "oauth-server", - "isFunc": false, - "items": [ - { - "id": "oauth-server", - "slug": "oauth-server", - "title": "OAuth Server", - "type": "function", - }, - { - "id": "oauth-server-approveauthorization", - "product": "auth", - "slug": "oauth-server-approveauthorization", - "title": "approveAuthorization", - "type": "function", - }, - { - "id": "oauth-server-denyauthorization", - "product": "auth", - "slug": "oauth-server-denyauthorization", - "title": "denyAuthorization", - "type": "function", - }, - { - "id": "oauth-server-getauthorizationdetails", - "product": "auth", - "slug": "oauth-server-getauthorizationdetails", - "title": "getAuthorizationDetails", - "type": "function", - }, - { - "id": "oauth-server-listgrants", - "product": "auth", - "slug": "oauth-server-listgrants", - "title": "listGrants", - "type": "function", - }, - { - "id": "oauth-server-revokegrant", - "product": "auth", - "slug": "oauth-server-revokegrant", - "title": "revokeGrant", - "type": "function", - }, - ], - "product": "auth", - "slug": "oauth-server", - "title": "OAuth Server", - "type": "function", - }, - { - "id": "passkey-admin", - "isFunc": false, - "items": [ - { - "id": "passkey-admin", - "slug": "passkey-admin", - "title": "Passkey admin", - "type": "function", - }, - { - "id": "passkey-admin-deletepasskey", - "product": "auth", - "slug": "passkey-admin-deletepasskey", - "title": "deletePasskey", - "type": "function", - }, - { - "id": "passkey-admin-listpasskeys", - "product": "auth", - "slug": "passkey-admin-listpasskeys", - "title": "listPasskeys", - "type": "function", - }, - ], - "product": "auth", - "slug": "passkey-admin", - "title": "Passkey Admin", - "type": "function", - }, - ], - "title": "Auth", - "type": "category", - }, - { - "items": [ - { - "id": "functions-corsheaders", - "product": "edge-functions", - "slug": "functions-corsheaders", - "title": "corsHeaders", - "type": "function", - }, - { - "id": "functions-invoke", - "product": "edge-functions", - "slug": "functions-invoke", - "title": "invoke", - "type": "function", - }, - { - "id": "functions-setauth", - "product": "edge-functions", - "slug": "functions-setauth", - "title": "setAuth", - "type": "function", - }, - ], - "title": "Edge Functions", - "type": "category", - }, - { - "items": [ - { - "id": "channel", - "product": "realtime", - "slug": "channel", - "title": "channel", - "type": "function", - }, - { - "id": "connect", - "product": "realtime", - "slug": "connect", - "title": "connect", - "type": "function", - }, - { - "id": "connectionstate", - "product": "realtime", - "slug": "connectionstate", - "title": "connectionState", - "type": "function", - }, - { - "id": "disconnect", - "product": "realtime", - "slug": "disconnect", - "title": "disconnect", - "type": "function", - }, - { - "id": "endpointurl", - "product": "realtime", - "slug": "endpointurl", - "title": "endpointURL", - "type": "function", - }, - { - "id": "getchannels", - "product": "realtime", - "slug": "getchannels", - "title": "getChannels", - "type": "function", - }, - { - "id": "getwebsocketconstructor", - "product": "realtime", - "slug": "getwebsocketconstructor", - "title": "getWebSocketConstructor", - "type": "function", - }, - { - "id": "httpsend", - "product": "realtime", - "slug": "httpsend", - "title": "httpSend", - "type": "function", - }, - { - "id": "isconnected", - "product": "realtime", - "slug": "isconnected", - "title": "isConnected", - "type": "function", - }, - { - "id": "isconnecting", - "product": "realtime", - "slug": "isconnecting", - "title": "isConnecting", - "type": "function", - }, - { - "id": "isdisconnecting", - "product": "realtime", - "slug": "isdisconnecting", - "title": "isDisconnecting", - "type": "function", - }, - { - "id": "iswebsocketsupported", - "product": "realtime", - "slug": "iswebsocketsupported", - "title": "isWebSocketSupported", - "type": "function", - }, - { - "id": "log", - "product": "realtime", - "slug": "log", - "title": "log", - "type": "function", - }, - { - "id": "on", - "product": "realtime", - "slug": "on", - "title": "on", - "type": "function", - }, - { - "id": "onheartbeat", - "product": "realtime", - "slug": "onheartbeat", - "title": "onHeartbeat", - "type": "function", - }, - { - "id": "presencestate", - "product": "realtime", - "slug": "presencestate", - "title": "presenceState", - "type": "function", - }, - { - "id": "push", - "product": "realtime", - "slug": "push", - "title": "push", - "type": "function", - }, - { - "id": "removeallchannels", - "product": "realtime", - "slug": "removeallchannels", - "title": "removeAllChannels", - "type": "function", - }, - { - "id": "removechannel", - "product": "realtime", - "slug": "removechannel", - "title": "removeChannel", - "type": "function", - }, - { - "id": "send", - "product": "realtime", - "slug": "send", - "title": "send", - "type": "function", - }, - { - "id": "sendheartbeat", - "product": "realtime", - "slug": "sendheartbeat", - "title": "sendHeartbeat", - "type": "function", - }, - { - "id": "setauth", - "product": "realtime", - "slug": "setauth", - "title": "setAuth", - "type": "function", - }, - { - "id": "subscribe", - "product": "realtime", - "slug": "subscribe", - "title": "subscribe", - "type": "function", - }, - { - "id": "teardown", - "product": "realtime", - "slug": "teardown", - "title": "teardown", - "type": "function", - }, - { - "id": "track", - "product": "realtime", - "slug": "track", - "title": "track", - "type": "function", - }, - { - "id": "unsubscribe", - "product": "realtime", - "slug": "unsubscribe", - "title": "unsubscribe", - "type": "function", - }, - { - "id": "untrack", - "product": "realtime", - "slug": "untrack", - "title": "untrack", - "type": "function", - }, - { - "id": "updatejoinpayload", - "product": "realtime", - "slug": "updatejoinpayload", - "title": "updateJoinPayload", - "type": "function", - }, - ], - "title": "Realtime", - "type": "category", - }, - { - "items": [ - { - "id": "analytics-buckets", - "isFunc": false, - "items": [ - { - "id": "analytics-buckets", - "slug": "analytics-buckets", - "title": "Analytics Buckets", - "type": "function", - }, - { - "id": "analytics-buckets-createbucket", - "product": "storage", - "slug": "analytics-buckets-createbucket", - "title": "createBucket", - "type": "function", - }, - { - "id": "analytics-buckets-deletebucket", - "product": "storage", - "slug": "analytics-buckets-deletebucket", - "title": "deleteBucket", - "type": "function", - }, - { - "id": "analytics-buckets-from", - "product": "storage", - "slug": "analytics-buckets-from", - "title": "from", - "type": "function", - }, - { - "id": "analytics-buckets-listbuckets", - "product": "storage", - "slug": "analytics-buckets-listbuckets", - "title": "listBuckets", - "type": "function", - }, - ], - "product": "storage", - "slug": "analytics-buckets", - "title": "Analytics Buckets", - "type": "function", - }, - { - "id": "file-buckets", - "isFunc": false, - "items": [ - { - "id": "file-buckets", - "slug": "file-buckets", - "title": "File Buckets", - "type": "function", - }, - { - "id": "file-buckets-copy", - "product": "storage", - "slug": "file-buckets-copy", - "title": "copy", - "type": "function", - }, - { - "id": "file-buckets-createbucket", - "product": "storage", - "slug": "file-buckets-createbucket", - "title": "createBucket", - "type": "function", - }, - { - "id": "file-buckets-createsigneduploadurl", - "product": "storage", - "slug": "file-buckets-createsigneduploadurl", - "title": "createSignedUploadUrl", - "type": "function", - }, - { - "id": "file-buckets-createsignedurl", - "product": "storage", - "slug": "file-buckets-createsignedurl", - "title": "createSignedUrl", - "type": "function", - }, - { - "id": "file-buckets-createsignedurls", - "product": "storage", - "slug": "file-buckets-createsignedurls", - "title": "createSignedUrls", - "type": "function", - }, - { - "id": "file-buckets-deletebucket", - "product": "storage", - "slug": "file-buckets-deletebucket", - "title": "deleteBucket", - "type": "function", - }, - { - "id": "file-buckets-download", - "product": "storage", - "slug": "file-buckets-download", - "title": "download", - "type": "function", - }, - { - "id": "file-buckets-emptybucket", - "product": "storage", - "slug": "file-buckets-emptybucket", - "title": "emptyBucket", - "type": "function", - }, - { - "id": "file-buckets-exists", - "product": "storage", - "slug": "file-buckets-exists", - "title": "exists", - "type": "function", - }, - { - "id": "file-buckets-from", - "product": "storage", - "slug": "file-buckets-from", - "title": "from", - "type": "function", - }, - { - "id": "file-buckets-getbucket", - "product": "storage", - "slug": "file-buckets-getbucket", - "title": "getBucket", - "type": "function", - }, - { - "id": "file-buckets-getpublicurl", - "product": "storage", - "slug": "file-buckets-getpublicurl", - "title": "getPublicUrl", - "type": "function", - }, - { - "id": "file-buckets-info", - "product": "storage", - "slug": "file-buckets-info", - "title": "info", - "type": "function", - }, - { - "id": "file-buckets-list", - "product": "storage", - "slug": "file-buckets-list", - "title": "list", - "type": "function", - }, - { - "id": "file-buckets-listbuckets", - "product": "storage", - "slug": "file-buckets-listbuckets", - "title": "listBuckets", - "type": "function", - }, - { - "id": "file-buckets-listv2", - "product": "storage", - "slug": "file-buckets-listv2", - "title": "listV2", - "type": "function", - }, - { - "id": "file-buckets-move", - "product": "storage", - "slug": "file-buckets-move", - "title": "move", - "type": "function", - }, - { - "id": "file-buckets-remove", - "product": "storage", - "slug": "file-buckets-remove", - "title": "remove", - "type": "function", - }, - { - "id": "file-buckets-update", - "product": "storage", - "slug": "file-buckets-update", - "title": "update", - "type": "function", - }, - { - "id": "file-buckets-updatebucket", - "product": "storage", - "slug": "file-buckets-updatebucket", - "title": "updateBucket", - "type": "function", - }, - { - "id": "file-buckets-upload", - "product": "storage", - "slug": "file-buckets-upload", - "title": "upload", - "type": "function", - }, - { - "id": "file-buckets-uploadtosignedurl", - "product": "storage", - "slug": "file-buckets-uploadtosignedurl", - "title": "uploadToSignedUrl", - "type": "function", - }, - ], - "product": "storage", - "slug": "file-buckets", - "title": "File Buckets", - "type": "function", - }, - { - "id": "vector-buckets", - "isFunc": false, - "items": [ - { - "id": "vector-buckets", - "slug": "vector-buckets", - "title": "Vector Buckets", - "type": "function", - }, - { - "id": "vector-buckets-createbucket", - "product": "storage", - "slug": "vector-buckets-createbucket", - "title": "createBucket", - "type": "function", - }, - { - "id": "vector-buckets-createindex", - "product": "storage", - "slug": "vector-buckets-createindex", - "title": "createIndex", - "type": "function", - }, - { - "id": "vector-buckets-deletebucket", - "product": "storage", - "slug": "vector-buckets-deletebucket", - "title": "deleteBucket", - "type": "function", - }, - { - "id": "vector-buckets-deleteindex", - "product": "storage", - "slug": "vector-buckets-deleteindex", - "title": "deleteIndex", - "type": "function", - }, - { - "id": "vector-buckets-deletevectors", - "product": "storage", - "slug": "vector-buckets-deletevectors", - "title": "deleteVectors", - "type": "function", - }, - { - "id": "vector-buckets-from", - "product": "storage", - "slug": "vector-buckets-from", - "title": "from", - "type": "function", - }, - { - "id": "vector-buckets-getbucket", - "product": "storage", - "slug": "vector-buckets-getbucket", - "title": "getBucket", - "type": "function", - }, - { - "id": "vector-buckets-getindex", - "product": "storage", - "slug": "vector-buckets-getindex", - "title": "getIndex", - "type": "function", - }, - { - "id": "vector-buckets-getvectors", - "product": "storage", - "slug": "vector-buckets-getvectors", - "title": "getVectors", - "type": "function", - }, - { - "id": "vector-buckets-index", - "product": "storage", - "slug": "vector-buckets-index", - "title": "index", - "type": "function", - }, - { - "id": "vector-buckets-listbuckets", - "product": "storage", - "slug": "vector-buckets-listbuckets", - "title": "listBuckets", - "type": "function", - }, - { - "id": "vector-buckets-listindexes", - "product": "storage", - "slug": "vector-buckets-listindexes", - "title": "listIndexes", - "type": "function", - }, - { - "id": "vector-buckets-listvectors", - "product": "storage", - "slug": "vector-buckets-listvectors", - "title": "listVectors", - "type": "function", - }, - { - "id": "vector-buckets-putvectors", - "product": "storage", - "slug": "vector-buckets-putvectors", - "title": "putVectors", - "type": "function", - }, - { - "id": "vector-buckets-queryvectors", - "product": "storage", - "slug": "vector-buckets-queryvectors", - "title": "queryVectors", - "type": "function", - }, - ], - "product": "storage", - "slug": "vector-buckets", - "title": "Vector Buckets", - "type": "function", - }, - ], - "title": "Storage", - "type": "category", - }, - ], - "typeSpec": { - "methods": { - "@supabase/auth-js.AuthApiError.constructor": { - "comment": undefined, - "name": "@supabase/auth-js.AuthApiError.constructor", - "params": [ - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "name": "code", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - { - "name": "string", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - ], - "ret": { - "type": { - "name": "AuthApiError", - "type": "nameOnly", - }, - }, - }, - "@supabase/auth-js.AuthApiError.toJSON": { - "comment": undefined, - "name": "@supabase/auth-js.AuthApiError.toJSON", - "params": [], - "ret": { - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - undefined, - { - "name": "ErrorCode", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - { - "name": "number", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - }, - "@supabase/auth-js.AuthError.constructor": { - "comment": undefined, - "name": "@supabase/auth-js.AuthError.constructor", - "params": [ - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "status", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "code", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "ret": { - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - }, - "@supabase/auth-js.AuthError.toJSON": { - "comment": undefined, - "name": "@supabase/auth-js.AuthError.toJSON", - "params": [], - "ret": { - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - undefined, - { - "name": "ErrorCode", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - { - "name": "number", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - }, - "@supabase/auth-js.AuthImplicitGrantRedirectError.constructor": { - "comment": undefined, - "name": "@supabase/auth-js.AuthImplicitGrantRedirectError.constructor", - "params": [ - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "details", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "error", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - }, - ], - "ret": { - "type": { - "name": "AuthImplicitGrantRedirectError", - "type": "nameOnly", - }, - }, - }, - "@supabase/auth-js.AuthImplicitGrantRedirectError.toJSON": { - "comment": undefined, - "name": "@supabase/auth-js.AuthImplicitGrantRedirectError.toJSON", - "params": [], - "ret": { - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - undefined, - { - "name": "ErrorCode", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - { - "name": "details", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "error", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - }, - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - { - "name": "number", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - }, - "@supabase/auth-js.AuthInvalidCredentialsError.constructor": { - "comment": undefined, - "name": "@supabase/auth-js.AuthInvalidCredentialsError.constructor", - "params": [ - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "ret": { - "type": { - "name": "AuthInvalidCredentialsError", - "type": "nameOnly", - }, - }, - }, - "@supabase/auth-js.AuthInvalidCredentialsError.toJSON": { - "comment": undefined, - "name": "@supabase/auth-js.AuthInvalidCredentialsError.toJSON", - "params": [], - "ret": { - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - undefined, - { - "name": "ErrorCode", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - { - "name": "number", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - }, - "@supabase/auth-js.AuthInvalidJwtError.constructor": { - "comment": undefined, - "name": "@supabase/auth-js.AuthInvalidJwtError.constructor", - "params": [ - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "ret": { - "type": { - "name": "AuthInvalidJwtError", - "type": "nameOnly", - }, - }, - }, - "@supabase/auth-js.AuthInvalidJwtError.toJSON": { - "comment": undefined, - "name": "@supabase/auth-js.AuthInvalidJwtError.toJSON", - "params": [], - "ret": { - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - undefined, - { - "name": "ErrorCode", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - { - "name": "number", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - }, - "@supabase/auth-js.AuthInvalidTokenResponseError.constructor": { - "comment": undefined, - "name": "@supabase/auth-js.AuthInvalidTokenResponseError.constructor", - "params": [], - "ret": { - "type": { - "name": "AuthInvalidTokenResponseError", - "type": "nameOnly", - }, - }, - }, - "@supabase/auth-js.AuthInvalidTokenResponseError.toJSON": { - "comment": undefined, - "name": "@supabase/auth-js.AuthInvalidTokenResponseError.toJSON", - "params": [], - "ret": { - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - undefined, - { - "name": "ErrorCode", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - { - "name": "number", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - }, - "@supabase/auth-js.AuthOAuthServerApi.approveAuthorization": { - "comment": { - "shortText": "Approves an OAuth authorization request. -Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. - -After approval, the user's consent is stored and an authorization code is generated. -The response contains a complete redirect URL with the authorization code and state.", - }, - "name": "@supabase/auth-js.AuthOAuthServerApi.approveAuthorization", - "params": [ - { - "comment": { - "shortText": "The authorization ID to approve", - }, - "name": "authorizationId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Optional parameters", - }, - "isOptional": true, - "name": "options", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "comment": { - "shortText": "If false (default), automatically redirects the browser to the OAuth client. If true, returns the redirect_url without automatic redirect (useful for custom handling).", - }, - "isOptional": true, - "name": "skipBrowserRedirect", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "AuthOAuthConsentResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": "OAuthRedirect", - "properties": [ - { - "comment": { - "shortText": "Complete redirect URL with authorization code and state parameters (e.g., "https://app.com/callback?code=xxx&state=yyy")", - }, - "name": "redirect_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.AuthOAuthServerApi.denyAuthorization": { - "comment": { - "shortText": "Denies an OAuth authorization request. -Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. - -After denial, the response contains a redirect URL with an OAuth error -(access_denied) to inform the OAuth client that the user rejected the request.", - }, - "name": "@supabase/auth-js.AuthOAuthServerApi.denyAuthorization", - "params": [ - { - "comment": { - "shortText": "The authorization ID to deny", - }, - "name": "authorizationId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Optional parameters", - }, - "isOptional": true, - "name": "options", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "comment": { - "shortText": "If false (default), automatically redirects the browser to the OAuth client. If true, returns the redirect_url without automatic redirect (useful for custom handling).", - }, - "isOptional": true, - "name": "skipBrowserRedirect", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "AuthOAuthConsentResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": "OAuthRedirect", - "properties": [ - { - "comment": { - "shortText": "Complete redirect URL with authorization code and state parameters (e.g., "https://app.com/callback?code=xxx&state=yyy")", - }, - "name": "redirect_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.AuthOAuthServerApi.getAuthorizationDetails": { - "comment": { - "shortText": "Retrieves details about an OAuth authorization request. -Used to display consent information to the user. -Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. - -This method returns one of two response types: -- \`OAuthAuthorizationDetails\`: User needs to consent - show consent page with client info -- \`OAuthRedirect\`: User already consented - redirect immediately to the OAuth client - -Use type narrowing to distinguish between the responses: -\`\`\`typescript -if ('authorization_id' in data) { - // Show consent page -} else { - // Redirect to data.redirect_url -} -\`\`\`", - }, - "name": "@supabase/auth-js.AuthOAuthServerApi.getAuthorizationDetails", - "params": [ - { - "comment": { - "shortText": "The authorization ID from the authorization request", - }, - "name": "authorizationId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "AuthOAuthAuthorizationDetailsResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "OAuthAuthorizationDetails", - "properties": [ - { - "comment": { - "shortText": "The authorization ID used to approve or deny the request", - }, - "name": "authorization_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth client requesting authorization", - }, - "name": "client", - "type": { - "name": "OAuthAuthorizationClient", - "properties": [ - { - "comment": { - "shortText": "Unique identifier for the OAuth client (UUID)", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URI of the OAuth client's logo", - }, - "name": "logo_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Human-readable name of the OAuth client", - }, - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URI of the OAuth client's website", - }, - "name": "uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "comment": { - "shortText": "The OAuth client's registered redirect URI (base URI without query parameters)", - }, - "name": "redirect_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Space-separated list of requested scopes (e.g., "openid profile email")", - }, - "name": "scope", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "User object associated with the authorization", - }, - "name": "user", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "comment": { - "shortText": "User email", - }, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "User ID (UUID)", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - { - "name": "OAuthRedirect", - "properties": [ - { - "comment": { - "shortText": "Complete redirect URL with authorization code and state parameters (e.g., "https://app.com/callback?code=xxx&state=yyy")", - }, - "name": "redirect_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.AuthOAuthServerApi.listGrants": { - "comment": { - "shortText": "Lists all OAuth grants that the authenticated user has authorized. -Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.", - }, - "name": "@supabase/auth-js.AuthOAuthServerApi.listGrants", - "params": [], - "ret": { - "type": { - "awaited": { - "name": "AuthOAuthGrantsResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "elemType": { - "name": "OAuthGrant", - "properties": [ - { - "comment": { - "shortText": "OAuth client information", - }, - "name": "client", - "type": { - "name": "OAuthAuthorizationClient", - "properties": [ - { - "comment": { - "shortText": "Unique identifier for the OAuth client (UUID)", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URI of the OAuth client's logo", - }, - "name": "logo_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Human-readable name of the OAuth client", - }, - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URI of the OAuth client's website", - }, - "name": "uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "comment": { - "shortText": "Timestamp when the grant was created (ISO 8601 date-time)", - }, - "name": "granted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Array of scopes granted to this client", - }, - "name": "scopes", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.AuthOAuthServerApi.revokeGrant": { - "comment": { - "shortText": "Revokes a user's OAuth grant for a specific client. -Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. - -Revocation marks consent as revoked, deletes active sessions for that OAuth client, -and invalidates associated refresh tokens.", - }, - "name": "@supabase/auth-js.AuthOAuthServerApi.revokeGrant", - "params": [ - { - "comment": { - "shortText": "Revocation options", - }, - "name": "options", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "comment": { - "shortText": "The OAuth client identifier (UUID) to revoke access for", - }, - "name": "clientId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "AuthOAuthRevokeGrantResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": undefined, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.AuthPKCECodeVerifierMissingError.constructor": { - "comment": undefined, - "name": "@supabase/auth-js.AuthPKCECodeVerifierMissingError.constructor", - "params": [], - "ret": { - "type": { - "name": "AuthPKCECodeVerifierMissingError", - "type": "nameOnly", - }, - }, - }, - "@supabase/auth-js.AuthPKCECodeVerifierMissingError.toJSON": { - "comment": undefined, - "name": "@supabase/auth-js.AuthPKCECodeVerifierMissingError.toJSON", - "params": [], - "ret": { - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - undefined, - { - "name": "ErrorCode", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - { - "name": "number", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - }, - "@supabase/auth-js.AuthPKCEGrantCodeExchangeError.constructor": { - "comment": undefined, - "name": "@supabase/auth-js.AuthPKCEGrantCodeExchangeError.constructor", - "params": [ - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "details", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "error", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - }, - ], - "ret": { - "type": { - "name": "AuthPKCEGrantCodeExchangeError", - "type": "nameOnly", - }, - }, - }, - "@supabase/auth-js.AuthPKCEGrantCodeExchangeError.toJSON": { - "comment": undefined, - "name": "@supabase/auth-js.AuthPKCEGrantCodeExchangeError.toJSON", - "params": [], - "ret": { - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - undefined, - { - "name": "ErrorCode", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - { - "name": "details", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "error", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - }, - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - { - "name": "number", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - }, - "@supabase/auth-js.AuthPasskeyApi.delete": { - "comment": { - "shortText": "Deletes a passkey for the currently signed-in user.", - }, - "name": "@supabase/auth-js.AuthPasskeyApi.delete", - "params": [ - { - "name": "params", - "type": { - "name": "PasskeyDeleteParams", - "properties": [ - { - "comment": { - "shortText": "UUID of the passkey to delete", - }, - "name": "passkeyId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "AuthPasskeyDeleteResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.AuthPasskeyApi.list": { - "comment": { - "shortText": "Lists all passkeys registered for the currently signed-in user.", - }, - "name": "@supabase/auth-js.AuthPasskeyApi.list", - "params": [], - "ret": { - "type": { - "awaited": { - "name": "AuthPasskeyListResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "elemType": { - "name": "PasskeyListItem", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_used_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.AuthPasskeyApi.startAuthentication": { - "comment": { - "shortText": "Starts the passkey authentication ceremony. Fetches an authentication -challenge and credential request options from the server. Used as the -first step of a two-step sign-in flow when the caller wants to handle -\`navigator.credentials.get()\` themselves.", - }, - "name": "@supabase/auth-js.AuthPasskeyApi.startAuthentication", - "params": [ - { - "isOptional": true, - "name": "params", - "type": { - "name": "StartPasskeyAuthenticationParams", - "properties": [ - { - "isOptional": true, - "name": "options", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "isOptional": true, - "name": "captchaToken", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "AuthPasskeyAuthenticationOptionsResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": "PasskeyAuthenticationOptionsResponse", - "properties": [ - { - "name": "challenge_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "expires_at", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "name": "options", - "type": { - "name": "ServerCredentialRequestOptions", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.AuthPasskeyApi.startRegistration": { - "comment": { - "shortText": "Starts the passkey registration ceremony. Fetches a registration challenge -and credential creation options from the server. Used as the first step of -a two-step registration flow when the caller wants to handle -\`navigator.credentials.create()\` themselves.", - }, - "name": "@supabase/auth-js.AuthPasskeyApi.startRegistration", - "params": [], - "ret": { - "type": { - "awaited": { - "name": "AuthPasskeyRegistrationOptionsResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": "PasskeyRegistrationOptionsResponse", - "properties": [ - { - "name": "challenge_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "expires_at", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "name": "options", - "type": { - "name": "ServerCredentialCreationOptions", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.AuthPasskeyApi.update": { - "comment": { - "shortText": "Updates a passkey's friendly name.", - }, - "name": "@supabase/auth-js.AuthPasskeyApi.update", - "params": [ - { - "name": "params", - "type": { - "name": "PasskeyUpdateParams", - "properties": [ - { - "comment": { - "shortText": "New friendly name (max 120 chars)", - }, - "name": "friendlyName", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "UUID of the passkey to update", - }, - "name": "passkeyId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "AuthPasskeyUpdateResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": "PasskeyListItem", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_used_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.AuthPasskeyApi.verifyAuthentication": { - "comment": { - "shortText": "Verifies a passkey authentication credential against a previously issued -challenge. Used as the second step of a two-step sign-in flow.", - }, - "name": "@supabase/auth-js.AuthPasskeyApi.verifyAuthentication", - "params": [ - { - "name": "params", - "type": { - "name": "VerifyPasskeyAuthenticationParams", - "properties": [ - { - "comment": { - "shortText": "Challenge ID from startAuthentication", - }, - "name": "challengeId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Serialized credential from navigator.credentials.get()", - }, - "name": "credential", - "type": { - "name": "ServerCredentialResponse", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "AuthPasskeyAuthenticationVerifyResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "session", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Session", - "properties": [ - { - "comment": { - "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value.", - }, - "name": "access_token", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed.", - }, - "isOptional": true, - "name": "expires_at", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed.", - }, - "name": "expires_in", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API. -Not all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token.", - }, - "isOptional": true, - "name": "provider_refresh_token", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "string", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used.", - }, - "isOptional": true, - "name": "provider_token", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "string", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "A one-time used refresh token that never expires.", - }, - "name": "refresh_token", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "token_type", - "type": { - "type": "literal", - "value": "bearer", - }, - }, - { - "comment": { - "shortText": "When using a separate user storage, accessing properties of this object will throw an error.", - }, - "name": "user", - "type": { - "name": "User", - "properties": [ - { - "isOptional": true, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "banned_until", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmation_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "deleted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_change_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "factors", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "invited_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_sso_user", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "recovery_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - { - "type": "literal", - "value": null, - }, - ], - "type": "union", - }, - }, - { - "name": "user", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "User", - "properties": [ - { - "isOptional": true, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "banned_until", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmation_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "deleted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_change_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "factors", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "invited_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_sso_user", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "recovery_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - { - "type": "literal", - "value": null, - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.AuthPasskeyApi.verifyRegistration": { - "comment": { - "shortText": "Verifies a passkey registration credential against a previously issued -challenge. Used as the second step of a two-step registration flow.", - }, - "name": "@supabase/auth-js.AuthPasskeyApi.verifyRegistration", - "params": [ - { - "name": "params", - "type": { - "name": "VerifyPasskeyRegistrationParams", - "properties": [ - { - "comment": { - "shortText": "Challenge ID from startRegistration", - }, - "name": "challengeId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Serialized credential from navigator.credentials.create()", - }, - "name": "credential", - "type": { - "name": "ServerCredentialResponse", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "AuthPasskeyRegistrationVerifyResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": "PasskeyMetadata", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.AuthRefreshDiscardedError.constructor": { - "comment": undefined, - "name": "@supabase/auth-js.AuthRefreshDiscardedError.constructor", - "params": [ - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "ret": { - "type": { - "name": "AuthRefreshDiscardedError", - "type": "nameOnly", - }, - }, - }, - "@supabase/auth-js.AuthRefreshDiscardedError.toJSON": { - "comment": undefined, - "name": "@supabase/auth-js.AuthRefreshDiscardedError.toJSON", - "params": [], - "ret": { - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - undefined, - { - "name": "ErrorCode", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - { - "name": "number", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - }, - "@supabase/auth-js.AuthRetryableFetchError.constructor": { - "comment": undefined, - "name": "@supabase/auth-js.AuthRetryableFetchError.constructor", - "params": [ - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - ], - "ret": { - "type": { - "name": "AuthRetryableFetchError", - "type": "nameOnly", - }, - }, - }, - "@supabase/auth-js.AuthRetryableFetchError.toJSON": { - "comment": undefined, - "name": "@supabase/auth-js.AuthRetryableFetchError.toJSON", - "params": [], - "ret": { - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - undefined, - { - "name": "ErrorCode", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - { - "name": "number", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - }, - "@supabase/auth-js.AuthSessionMissingError.constructor": { - "comment": undefined, - "name": "@supabase/auth-js.AuthSessionMissingError.constructor", - "params": [], - "ret": { - "type": { - "name": "AuthSessionMissingError", - "type": "nameOnly", - }, - }, - }, - "@supabase/auth-js.AuthSessionMissingError.toJSON": { - "comment": undefined, - "name": "@supabase/auth-js.AuthSessionMissingError.toJSON", - "params": [], - "ret": { - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - undefined, - { - "name": "ErrorCode", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - { - "name": "number", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - }, - "@supabase/auth-js.AuthUnknownError.constructor": { - "comment": undefined, - "name": "@supabase/auth-js.AuthUnknownError.constructor", - "params": [ - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "originalError", - "type": { - "name": "unknown", - "type": "intrinsic", - }, - }, - ], - "ret": { - "type": { - "name": "AuthUnknownError", - "type": "nameOnly", - }, - }, - }, - "@supabase/auth-js.AuthUnknownError.toJSON": { - "comment": undefined, - "name": "@supabase/auth-js.AuthUnknownError.toJSON", - "params": [], - "ret": { - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - undefined, - { - "name": "ErrorCode", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - { - "name": "number", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - }, - "@supabase/auth-js.AuthWeakPasswordError.constructor": { - "comment": undefined, - "name": "@supabase/auth-js.AuthWeakPasswordError.constructor", - "params": [ - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "name": "reasons", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "length", - }, - { - "type": "literal", - "value": "characters", - }, - { - "type": "literal", - "value": "pwned", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "ret": { - "type": { - "name": "AuthWeakPasswordError", - "type": "nameOnly", - }, - }, - }, - "@supabase/auth-js.AuthWeakPasswordError.toJSON": { - "comment": undefined, - "name": "@supabase/auth-js.AuthWeakPasswordError.toJSON", - "params": [], - "ret": { - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - undefined, - { - "name": "ErrorCode", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "reasons", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "length", - }, - { - "type": "literal", - "value": "characters", - }, - { - "type": "literal", - "value": "pwned", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - { - "name": "number", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - }, - "@supabase/auth-js.CustomAuthError.constructor": { - "comment": undefined, - "name": "@supabase/auth-js.CustomAuthError.constructor", - "params": [ - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "name": "code", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - { - "name": "string", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - ], - "ret": { - "type": { - "name": "CustomAuthError", - "type": "nameOnly", - }, - }, - }, - "@supabase/auth-js.CustomAuthError.toJSON": { - "comment": undefined, - "name": "@supabase/auth-js.CustomAuthError.toJSON", - "params": [], - "ret": { - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "code", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - undefined, - { - "name": "ErrorCode", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "undefined", - "type": "intrinsic", - }, - { - "name": "number", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminApi.constructor": { - "comment": { - "examples": [ - { - "code": "\`\`\`ts -import { createClient } from '@supabase/supabase-js' - -const supabase = createClient('https://xyzcompany.supabase.co', 'your-secret-key') -const { data, error } = await supabase.auth.admin.listUsers() -\`\`\`", - "data": undefined, - "description": undefined, - "id": "using-supabase-js-recommended", - "name": "Using supabase-js (recommended)", - "response": undefined, - }, - { - "code": "\`\`\`ts -import { GoTrueAdminApi } from '@supabase/auth-js' - -const admin = new GoTrueAdminApi({ - url: 'https://xyzcompany.supabase.co/auth/v1', - headers: { Authorization: \`Bearer \${process.env.SUPABASE_SECRET_KEY}\` }, -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "standalone-import-for-bundle-sensitive-environments", - "name": "Standalone import for bundle-sensitive environments", - "response": undefined, - }, - ], - "shortText": "Creates an admin API client that can be used to manage users and OAuth clients.", - }, - "name": "@supabase/auth-js.GoTrueAdminApi.constructor", - "params": [ - { - "name": Symbol(anonymous), - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "isOptional": true, - "name": "experimental", - "type": { - "name": "ExperimentalFeatureFlags", - "properties": [ - { - "comment": { - "shortText": "Enables passkey support: - - \`auth.signInWithPasskey()\`, \`auth.registerPasskey()\` - - \`auth.passkey.*\` - - \`auth.admin.passkey.*\` - -Defaults to \`false\`. Calling any passkey method while this flag is -disabled throws a descriptive error at call time.", - }, - "isOptional": true, - "name": "passkey", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "isOptional": true, - "name": "fetch", - "type": { - "comment": { - "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)", - }, - "name": Symbol(anonymous), - "params": [ - { - "name": "input", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "URL", - "type": "nameOnly", - }, - { - "name": "RequestInfo", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - { - "isOptional": true, - "name": "init", - "type": { - "name": "RequestInit", - "type": "nameOnly", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "Response", - "type": "nameOnly", - }, - "name": "Promise", - "type": "promise", - }, - }, - "type": "function", - }, - }, - { - "isOptional": true, - "name": "headers", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "string", - "type": "intrinsic", - }, - }, - }, - { - "name": "url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "name": "GoTrueAdminApi", - "type": "nameOnly", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminApi.createUser": { - "comment": { - "examples": [ - { - "code": "\`\`\`js -const { data, error } = await supabase.auth.admin.createUser({ - email: 'user@email.com', - password: 'password', - user_metadata: { name: 'Yoda' } -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "with-custom-user-metadata", - "name": "With custom user metadata", - "response": "\`\`\`json -{ - data: { - user: { - id: '1', - aud: 'authenticated', - role: 'authenticated', - email: 'example@email.com', - email_confirmed_at: '2024-01-01T00:00:00Z', - phone: '', - confirmation_sent_at: '2024-01-01T00:00:00Z', - confirmed_at: '2024-01-01T00:00:00Z', - last_sign_in_at: '2024-01-01T00:00:00Z', - app_metadata: {}, - user_metadata: {}, - identities: [ - { - "identity_id": "22222222-2222-2222-2222-222222222222", - "id": "1", - "user_id": "1", - "identity_data": { - "email": "example@email.com", - "email_verified": true, - "phone_verified": false, - "sub": "1" - }, - "provider": "email", - "last_sign_in_at": "2024-01-01T00:00:00Z", - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "email": "email@example.com" - }, - ], - created_at: '2024-01-01T00:00:00Z', - updated_at: '2024-01-01T00:00:00Z', - is_anonymous: false, - } - } - error: null -} -\`\`\`", - }, - { - "code": "\`\`\`js -const { data, error } = await supabase.auth.admin.createUser({ - email: 'user@email.com', - email_confirm: true -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "auto-confirm-the-user-s-email", - "name": "Auto-confirm the user's email", - "response": undefined, - }, - { - "code": "\`\`\`js -const { data, error } = await supabase.auth.admin.createUser({ - phone: '1234567890', - phone_confirm: true -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "auto-confirm-the-user-s-phone-number", - "name": "Auto-confirm the user's phone number", - "response": undefined, - }, - ], - "shortText": "Creates a new user. -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - "text": "- To confirm the user's email address or phone number, set \`email_confirm\` or \`phone_confirm\` to true. Both arguments default to false. -- \`createUser()\` will not send a confirmation email to the user. You can use [\`inviteUserByEmail()\`](/docs/reference/javascript/auth-admin-inviteuserbyemail) if you want to send them an email invite instead. -- If you are sure that the created user's email or phone number is legitimate and verified, you can set the \`email_confirm\` or \`phone_confirm\` param to \`true\`.", - }, - "name": "@supabase/auth-js.GoTrueAdminApi.createUser", - "params": [ - { - "name": "attributes", - "type": { - "name": "AdminUserAttributes", - "properties": [ - { - "comment": { - "shortText": "A custom data object to store the user's application specific metadata. This maps to the \`auth.users.app_metadata\` column. - -Only a service role can modify. - -The \`app_metadata\` should be a JSON object that includes app-specific info, such as identity providers, roles, and other -access control information.", - }, - "isOptional": true, - "name": "app_metadata", - "type": { - "name": "object", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Determines how long a user is banned for. - -The format for the ban duration follows a strict sequence of decimal numbers with a unit suffix. -Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". - -For example, some possible durations include: '300ms', '2h45m'. - -Setting the ban duration to 'none' lifts the ban on the user.", - }, - "isOptional": true, - "name": "ban_duration", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The user's current password - -This is only ever present when the user is resetting -their password and GOTRUE_SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD is true.", - }, - "isOptional": true, - "name": "current_password", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The user's email.", - }, - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Sets the user's email as confirmed when true, or unconfirmed when false. - -Only a service role can modify.", - }, - "isOptional": true, - "name": "email_confirm", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The \`id\` for the user. - -Allows you to overwrite the default \`id\` set for the user.", - }, - "isOptional": true, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The nonce sent for reauthentication if the user's password is to be updated. - -Call reauthenticate() to obtain the nonce first.", - }, - "isOptional": true, - "name": "nonce", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The user's password.", - }, - "isOptional": true, - "name": "password", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The \`password_hash\` for the user's password. - -Allows you to specify a password hash for the user. This is useful for migrating a user's password hash from another service. - -Supports bcrypt, scrypt (firebase), and argon2 password hashes.", - }, - "isOptional": true, - "name": "password_hash", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The user's phone.", - }, - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Sets the user's phone as confirmed when true, or unconfirmed when false. - -Only a service role can modify.", - }, - "isOptional": true, - "name": "phone_confirm", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The \`role\` claim set in the user's access token JWT. - -When a user signs up, this role is set to \`authenticated\` by default. You should only modify the \`role\` if you need to provision several levels of admin access that have different permissions on individual columns in your database. - -Setting this role to \`service_role\` is not recommended as it grants the user admin privileges.", - }, - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A custom data object to store the user's metadata. This maps to the \`auth.users.raw_user_meta_data\` column. - - -The \`user_metadata\` should be a JSON object that includes user-specific info, such as their first and last name. - -Note: When using the GoTrueAdminApi and wanting to modify a user's metadata, -this attribute is used instead of UserAttributes data.", - }, - "isOptional": true, - "name": "user_metadata", - "type": { - "name": "object", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "UserResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "user", - "type": { - "name": "User", - "properties": [ - { - "isOptional": true, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "banned_until", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmation_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "deleted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_change_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "factors", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "invited_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_sso_user", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "recovery_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "properties": [ - { - "name": "user", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminApi.deleteUser": { - "comment": { - "examples": [ - { - "code": "\`\`\`js -const { data, error } = await supabase.auth.admin.deleteUser( - '715ed5db-f090-4b8c-a067-640ecee36aa0' -) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "removes-a-user", - "name": "Removes a user", - "response": "\`\`\`json -{ - "data": { - "user": {} - }, - "error": null -} -\`\`\`", - }, - ], - "shortText": "Delete a user. Requires a \`service_role\` key.", - "text": "- The \`deleteUser()\` method requires the user's ID, which maps to the \`auth.users.id\` column.", - }, - "name": "@supabase/auth-js.GoTrueAdminApi.deleteUser", - "params": [ - { - "comment": { - "shortText": "The user id you want to remove.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "If true, then the user will be soft-deleted from the auth schema. Soft deletion allows user identification from the hashed user ID but is not reversible. -Defaults to false for backward compatibility. - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - }, - "name": "shouldSoftDelete", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "UserResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "user", - "type": { - "name": "User", - "properties": [ - { - "isOptional": true, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "banned_until", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmation_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "deleted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_change_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "factors", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "invited_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_sso_user", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "recovery_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "properties": [ - { - "name": "user", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminApi.generateLink": { - "comment": { - "examples": [ - { - "code": "\`\`\`js -const { data, error } = await supabase.auth.admin.generateLink({ - type: 'signup', - email: 'email@example.com', - password: 'secret' -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "generate-a-signup-link", - "name": "Generate a signup link", - "response": "\`\`\`json -{ - "data": { - "properties": { - "action_link": "", - "email_otp": "999999", - "hashed_token": "", - "verification_type": "signup" - }, - "user": { - "id": "11111111-1111-1111-1111-111111111111", - "aud": "authenticated", - "role": "authenticated", - "email": "email@example.com", - "phone": "", - "confirmation_sent_at": "2024-01-01T00:00:00Z", - "app_metadata": { - "provider": "email", - "providers": [ - "email" - ] - }, - "user_metadata": {}, - "identities": [ - { - "identity_id": "22222222-2222-2222-2222-222222222222", - "id": "11111111-1111-1111-1111-111111111111", - "user_id": "11111111-1111-1111-1111-111111111111", - "identity_data": { - "email": "email@example.com", - "email_verified": false, - "phone_verified": false, - "sub": "11111111-1111-1111-1111-111111111111" - }, - "provider": "email", - "last_sign_in_at": "2024-01-01T00:00:00Z", - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "email": "email@example.com" - } - ], - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "is_anonymous": false - } - }, - "error": null -} -\`\`\`", - }, - { - "code": "\`\`\`js -const { data, error } = await supabase.auth.admin.generateLink({ - type: 'invite', - email: 'email@example.com' -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "generate-an-invite-link", - "name": "Generate an invite link", - "response": undefined, - }, - { - "code": "\`\`\`js -const { data, error } = await supabase.auth.admin.generateLink({ - type: 'magiclink', - email: 'email@example.com' -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "generate-a-magic-link", - "name": "Generate a magic link", - "response": undefined, - }, - { - "code": "\`\`\`js -const { data, error } = await supabase.auth.admin.generateLink({ - type: 'recovery', - email: 'email@example.com' -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "generate-a-recovery-link", - "name": "Generate a recovery link", - "response": undefined, - }, - { - "code": "\`\`\`js -// generate an email change link to be sent to the current email address -const { data, error } = await supabase.auth.admin.generateLink({ - type: 'email_change_current', - email: 'current.email@example.com', - newEmail: 'new.email@example.com' -}) - -// generate an email change link to be sent to the new email address -const { data, error } = await supabase.auth.admin.generateLink({ - type: 'email_change_new', - email: 'current.email@example.com', - newEmail: 'new.email@example.com' -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "generate-links-to-change-current-email-address", - "name": "Generate links to change current email address", - "response": undefined, - }, - ], - "shortText": "Generates email links and OTPs to be sent via a custom email provider.", - "text": "- The following types can be passed into \`generateLink()\`: \`signup\`, \`magiclink\`, \`invite\`, \`recovery\`, \`email_change_current\`, \`email_change_new\`, \`phone_change\`. -- \`generateLink()\` only generates the email link for \`email_change_email\` if the **Secure email change** is enabled in your project's [email auth provider settings](/dashboard/project/_/auth/providers). -- \`generateLink()\` handles the creation of the user for \`signup\`, \`invite\` and \`magiclink\`.", - }, - "name": "@supabase/auth-js.GoTrueAdminApi.generateLink", - "params": [ - { - "name": "params", - "type": { - "name": "GenerateLinkParams", - "subTypes": [ - { - "name": "GenerateSignupLinkParams", - "properties": [ - { - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "options", - "type": undefined, - }, - { - "name": "password", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "type", - "type": { - "type": "literal", - "value": "signup", - }, - }, - ], - "type": "object", - }, - { - "name": "GenerateInviteOrMagiclinkParams", - "properties": [ - { - "comment": { - "shortText": "The user's email", - }, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "options", - "type": undefined, - }, - { - "name": "type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "invite", - }, - { - "type": "literal", - "value": "magiclink", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - { - "name": "GenerateRecoveryLinkParams", - "properties": [ - { - "comment": { - "shortText": "The user's email", - }, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "options", - "type": undefined, - }, - { - "name": "type", - "type": { - "type": "literal", - "value": "recovery", - }, - }, - ], - "type": "object", - }, - { - "name": "GenerateEmailChangeLinkParams", - "properties": [ - { - "comment": { - "shortText": "The user's email", - }, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The user's new email. Only required if type is 'email_change_current' or 'email_change_new'.", - }, - "name": "newEmail", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "options", - "type": undefined, - }, - { - "name": "type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "email_change_current", - }, - { - "type": "literal", - "value": "email_change_new", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "GenerateLinkResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "properties", - "type": { - "name": "GenerateLinkProperties", - "properties": [ - { - "comment": { - "shortText": "The email link to send to the user. -The action_link follows the following format: auth/v1/verify?type={verification_type}&token={hashed_token}&redirect_to={redirect_to}", - }, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The raw email OTP. -You should send this in the email if you want your users to verify using an OTP instead of the action link.", - }, - "name": "email_otp", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The hashed token appended to the action link.", - }, - "name": "hashed_token", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The URL appended to the action link.", - }, - "name": "redirect_to", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification type that the email link is associated to.", - }, - "name": "verification_type", - "type": { - "name": "GenerateLinkType", - "subTypes": [ - { - "type": "literal", - "value": "signup", - }, - { - "type": "literal", - "value": "invite", - }, - { - "type": "literal", - "value": "magiclink", - }, - { - "type": "literal", - "value": "recovery", - }, - { - "type": "literal", - "value": "email_change_current", - }, - { - "type": "literal", - "value": "email_change_new", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "user", - "type": { - "name": "User", - "properties": [ - { - "isOptional": true, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "banned_until", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmation_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "deleted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_change_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "factors", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "invited_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_sso_user", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "recovery_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "properties": [ - { - "name": "properties", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "user", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminApi.getUserById": { - "comment": { - "examples": [ - { - "code": "\`\`\`js -const { data, error } = await supabase.auth.admin.getUserById(1) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "fetch-the-user-object-using-the-access-token-jwt", - "name": "Fetch the user object using the access_token jwt", - "response": "\`\`\`json -{ - data: { - user: { - id: '1', - aud: 'authenticated', - role: 'authenticated', - email: 'example@email.com', - email_confirmed_at: '2024-01-01T00:00:00Z', - phone: '', - confirmation_sent_at: '2024-01-01T00:00:00Z', - confirmed_at: '2024-01-01T00:00:00Z', - last_sign_in_at: '2024-01-01T00:00:00Z', - app_metadata: {}, - user_metadata: {}, - identities: [ - { - "identity_id": "22222222-2222-2222-2222-222222222222", - "id": "1", - "user_id": "1", - "identity_data": { - "email": "example@email.com", - "email_verified": true, - "phone_verified": false, - "sub": "1" - }, - "provider": "email", - "last_sign_in_at": "2024-01-01T00:00:00Z", - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "email": "email@example.com" - }, - ], - created_at: '2024-01-01T00:00:00Z', - updated_at: '2024-01-01T00:00:00Z', - is_anonymous: false, - } - } - error: null -} -\`\`\`", - }, - ], - "shortText": "Get user by id.", - "text": "- Fetches the user object from the database based on the user's id. -- The \`getUserById()\` method requires the user's id which maps to the \`auth.users.id\` column.", - }, - "name": "@supabase/auth-js.GoTrueAdminApi.getUserById", - "params": [ - { - "comment": { - "shortText": "The user's unique identifier - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - }, - "name": "uid", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "UserResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "user", - "type": { - "name": "User", - "properties": [ - { - "isOptional": true, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "banned_until", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmation_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "deleted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_change_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "factors", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "invited_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_sso_user", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "recovery_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "properties": [ - { - "name": "user", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminApi.inviteUserByEmail": { - "comment": { - "examples": [ - { - "code": "\`\`\`js -const { data, error } = await supabase.auth.admin.inviteUserByEmail('email@example.com') -\`\`\`", - "data": undefined, - "description": undefined, - "id": "invite-a-user", - "name": "Invite a user", - "response": "\`\`\`json -{ - "data": { - "user": { - "id": "11111111-1111-1111-1111-111111111111", - "aud": "authenticated", - "role": "authenticated", - "email": "example@email.com", - "invited_at": "2024-01-01T00:00:00Z", - "phone": "", - "confirmation_sent_at": "2024-01-01T00:00:00Z", - "app_metadata": { - "provider": "email", - "providers": [ - "email" - ] - }, - "user_metadata": {}, - "identities": [ - { - "identity_id": "22222222-2222-2222-2222-222222222222", - "id": "11111111-1111-1111-1111-111111111111", - "user_id": "11111111-1111-1111-1111-111111111111", - "identity_data": { - "email": "example@email.com", - "email_verified": false, - "phone_verified": false, - "sub": "11111111-1111-1111-1111-111111111111" - }, - "provider": "email", - "last_sign_in_at": "2024-01-01T00:00:00Z", - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "email": "example@email.com" - } - ], - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "is_anonymous": false - } - }, - "error": null -} -\`\`\`", - }, - ], - "shortText": "Sends an invite link to an email address.", - "text": "- Sends an invite link to the user's email address. -- The \`inviteUserByEmail()\` method is typically used by administrators to invite users to join the application. -- Note that PKCE is not supported when using \`inviteUserByEmail\`. This is because the browser initiating the invite is often different from the browser accepting the invite which makes it difficult to provide the security guarantees required of the PKCE flow.", - }, - "name": "@supabase/auth-js.GoTrueAdminApi.inviteUserByEmail", - "params": [ - { - "comment": { - "shortText": "The email address of the user.", - }, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Additional options to be included when inviting.", - }, - "name": "options", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "comment": { - "shortText": "A custom data object to store additional metadata about the user. This maps to the \`auth.users.user_metadata\` column.", - }, - "isOptional": true, - "name": "data", - "type": { - "name": "object", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The URL which will be appended to the email link sent to the user's email address. Once clicked the user will end up on this URL.", - }, - "isOptional": true, - "name": "redirectTo", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "UserResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "user", - "type": { - "name": "User", - "properties": [ - { - "isOptional": true, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "banned_until", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmation_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "deleted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_change_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "factors", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "invited_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_sso_user", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "recovery_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "properties": [ - { - "name": "user", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminApi.listUsers": { - "comment": { - "examples": [ - { - "code": "\`\`\`js -const { data: { users }, error } = await supabase.auth.admin.listUsers() -\`\`\`", - "data": undefined, - "description": undefined, - "id": "get-a-page-of-users", - "name": "Get a page of users", - "response": undefined, - }, - { - "code": "\`\`\`js -const { data: { users }, error } = await supabase.auth.admin.listUsers({ - page: 1, - perPage: 1000 -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "paginated-list-of-users", - "name": "Paginated list of users", - "response": undefined, - }, - ], - "shortText": "Get a list of users. - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - "text": "- Defaults to return 50 users per page.", - }, - "name": "@supabase/auth-js.GoTrueAdminApi.listUsers", - "params": [ - { - "comment": { - "shortText": "An object which supports \`page\` and \`perPage\` as numbers, to alter the paginated results.", - }, - "isOptional": true, - "name": "params", - "type": { - "name": "PageParams", - "properties": [ - { - "comment": { - "shortText": "The page number", - }, - "isOptional": true, - "name": "page", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Number of items returned per page", - }, - "isOptional": true, - "name": "perPage", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": undefined, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "users", - "type": undefined, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminApi.signOut": { - "comment": { - "shortText": "Removes a logged-in session.", - }, - "name": "@supabase/auth-js.GoTrueAdminApi.signOut", - "params": [ - { - "comment": { - "shortText": "A valid, logged-in JWT.", - }, - "name": "jwt", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The logout sope.", - }, - "name": "scope", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "global", - }, - { - "type": "literal", - "value": "local", - }, - { - "type": "literal", - "value": "others", - }, - ], - "type": "union", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "AuthError", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminApi.updateUserById": { - "comment": { - "examples": [ - { - "code": "\`\`\`typescript -// Server-side (Edge Function) -const { data, error } = await supabase.auth.admin.updateUserById( - userId, - { user_metadata: { preferences: { theme: 'dark' } } } -) - -// Client-side (to sync the changes) -const { data, error } = await supabase.auth.refreshSession() -// onAuthStateChange listeners will now be notified with updated user -\`\`\`", - "data": undefined, - "description": undefined, - "id": "example-1", - "name": "Example 1", - "response": undefined, - }, - { - "code": "\`\`\`js -const { data: user, error } = await supabase.auth.admin.updateUserById( - '11111111-1111-1111-1111-111111111111', - { email: 'new@email.com' } -) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "updates-a-user-s-email", - "name": "Updates a user's email", - "response": "\`\`\`json -{ - "data": { - "user": { - "id": "11111111-1111-1111-1111-111111111111", - "aud": "authenticated", - "role": "authenticated", - "email": "new@email.com", - "email_confirmed_at": "2024-01-01T00:00:00Z", - "phone": "", - "confirmed_at": "2024-01-01T00:00:00Z", - "recovery_sent_at": "2024-01-01T00:00:00Z", - "last_sign_in_at": "2024-01-01T00:00:00Z", - "app_metadata": { - "provider": "email", - "providers": [ - "email" - ] - }, - "user_metadata": { - "email": "example@email.com", - "email_verified": false, - "phone_verified": false, - "sub": "11111111-1111-1111-1111-111111111111" - }, - "identities": [ - { - "identity_id": "22222222-2222-2222-2222-222222222222", - "id": "11111111-1111-1111-1111-111111111111", - "user_id": "11111111-1111-1111-1111-111111111111", - "identity_data": { - "email": "example@email.com", - "email_verified": false, - "phone_verified": false, - "sub": "11111111-1111-1111-1111-111111111111" - }, - "provider": "email", - "last_sign_in_at": "2024-01-01T00:00:00Z", - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "email": "example@email.com" - } - ], - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "is_anonymous": false - } - }, - "error": null -} -\`\`\`", - }, - { - "code": "\`\`\`js -const { data: user, error } = await supabase.auth.admin.updateUserById( - '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4', - { password: 'new_password' } -) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "updates-a-user-s-password", - "name": "Updates a user's password", - "response": undefined, - }, - { - "code": "\`\`\`js -const { data: user, error } = await supabase.auth.admin.updateUserById( - '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4', - { user_metadata: { hello: 'world' } } -) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "updates-a-user-s-metadata", - "name": "Updates a user's metadata", - "response": undefined, - }, - { - "code": "\`\`\`js -const { data: user, error } = await supabase.auth.admin.updateUserById( - '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4', - { app_metadata: { plan: 'trial' } } -) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "updates-a-user-s-app-metadata", - "name": "Updates a user's app_metadata", - "response": undefined, - }, - { - "code": "\`\`\`js -const { data: user, error } = await supabase.auth.admin.updateUserById( - '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4', - { email_confirm: true } -) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "confirms-a-user-s-email-address", - "name": "Confirms a user's email address", - "response": undefined, - }, - { - "code": "\`\`\`js -const { data: user, error } = await supabase.auth.admin.updateUserById( - '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4', - { phone_confirm: true } -) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "confirms-a-user-s-phone-number", - "name": "Confirms a user's phone number", - "response": undefined, - }, - { - "code": "\`\`\`js -const { data: user, error } = await supabase.auth.admin.updateUserById( - '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4', - { ban_duration: '876000h' } -) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "ban-a-user-for-100-years", - "name": "Ban a user for 100 years", - "response": undefined, - }, - ], - "shortText": "Updates the user data. Changes are applied directly without confirmation flows.", - "text": "**Important:** This is a server-side operation and does **not** trigger client-side -\`onAuthStateChange\` listeners. The admin API has no connection to client state. - -To sync changes to the client after calling this method: -1. On the client, call \`supabase.auth.refreshSession()\` to fetch the updated user data -2. This will trigger the \`TOKEN_REFRESHED\` event and notify all listeners", - }, - "name": "@supabase/auth-js.GoTrueAdminApi.updateUserById", - "params": [ - { - "comment": { - "shortText": "The user's unique identifier", - }, - "name": "uid", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The data you want to update. - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - }, - "name": "attributes", - "type": { - "name": "AdminUserAttributes", - "properties": [ - { - "comment": { - "shortText": "A custom data object to store the user's application specific metadata. This maps to the \`auth.users.app_metadata\` column. - -Only a service role can modify. - -The \`app_metadata\` should be a JSON object that includes app-specific info, such as identity providers, roles, and other -access control information.", - }, - "isOptional": true, - "name": "app_metadata", - "type": { - "name": "object", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Determines how long a user is banned for. - -The format for the ban duration follows a strict sequence of decimal numbers with a unit suffix. -Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". - -For example, some possible durations include: '300ms', '2h45m'. - -Setting the ban duration to 'none' lifts the ban on the user.", - }, - "isOptional": true, - "name": "ban_duration", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The user's current password - -This is only ever present when the user is resetting -their password and GOTRUE_SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD is true.", - }, - "isOptional": true, - "name": "current_password", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The user's email.", - }, - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Sets the user's email as confirmed when true, or unconfirmed when false. - -Only a service role can modify.", - }, - "isOptional": true, - "name": "email_confirm", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The \`id\` for the user. - -Allows you to overwrite the default \`id\` set for the user.", - }, - "isOptional": true, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The nonce sent for reauthentication if the user's password is to be updated. - -Call reauthenticate() to obtain the nonce first.", - }, - "isOptional": true, - "name": "nonce", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The user's password.", - }, - "isOptional": true, - "name": "password", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The \`password_hash\` for the user's password. - -Allows you to specify a password hash for the user. This is useful for migrating a user's password hash from another service. - -Supports bcrypt, scrypt (firebase), and argon2 password hashes.", - }, - "isOptional": true, - "name": "password_hash", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The user's phone.", - }, - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Sets the user's phone as confirmed when true, or unconfirmed when false. - -Only a service role can modify.", - }, - "isOptional": true, - "name": "phone_confirm", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The \`role\` claim set in the user's access token JWT. - -When a user signs up, this role is set to \`authenticated\` by default. You should only modify the \`role\` if you need to provision several levels of admin access that have different permissions on individual columns in your database. - -Setting this role to \`service_role\` is not recommended as it grants the user admin privileges.", - }, - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A custom data object to store the user's metadata. This maps to the \`auth.users.raw_user_meta_data\` column. - - -The \`user_metadata\` should be a JSON object that includes user-specific info, such as their first and last name. - -Note: When using the GoTrueAdminApi and wanting to modify a user's metadata, -this attribute is used instead of UserAttributes data.", - }, - "isOptional": true, - "name": "user_metadata", - "type": { - "name": "object", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "UserResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "user", - "type": { - "name": "User", - "properties": [ - { - "isOptional": true, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "banned_until", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmation_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "deleted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_change_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "factors", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "invited_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_sso_user", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "recovery_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "properties": [ - { - "name": "user", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminCustomProvidersApi.createProvider": { - "comment": { - "shortText": "Creates a new custom OIDC/OAuth provider. - -For OIDC providers, the server fetches and validates the OpenID Connect discovery document -from the issuer's well-known endpoint (or the provided \`discovery_url\`) at creation time. -This may return a validation error (\`error_code: "validation_failed"\`) if the discovery -document is unreachable, not valid JSON, missing required fields, or if the issuer -in the document does not match the expected issuer. - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - }, - "name": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.createProvider", - "params": [ - { - "name": "params", - "type": { - "name": "CreateCustomProviderParams", - "properties": [ - { - "comment": { - "shortText": "Additional client IDs accepted during token validation", - }, - "isOptional": true, - "name": "acceptable_client_ids", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Mapping of provider attributes to Supabase user attributes", - }, - "isOptional": true, - "name": "attribute_mapping", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": "Record", - "type": "record", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "comment": { - "shortText": "Additional parameters sent with the authorization request", - }, - "isOptional": true, - "name": "authorization_params", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": "Record", - "type": "record", - "valueType": { - "name": "string", - "type": "intrinsic", - }, - }, - }, - { - "comment": { - "shortText": "OAuth2 authorization URL", - }, - "isOptional": true, - "name": "authorization_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth client ID", - }, - "name": "client_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth client secret (write-only, not returned in responses)", - }, - "name": "client_secret", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OIDC discovery URL", - }, - "isOptional": true, - "name": "discovery_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether email is optional for this provider", - }, - "isOptional": true, - "name": "email_optional", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether the provider is enabled", - }, - "isOptional": true, - "name": "enabled", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Provider identifier (e.g. \`custom:mycompany\`)", - }, - "name": "identifier", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OIDC issuer URL", - }, - "isOptional": true, - "name": "issuer", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "JWKS URI for token verification", - }, - "isOptional": true, - "name": "jwks_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Human-readable name", - }, - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether PKCE is enabled", - }, - "isOptional": true, - "name": "pkce_enabled", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Provider type", - }, - "name": "provider_type", - "type": { - "name": "CustomProviderType", - "subTypes": [ - { - "type": "literal", - "value": "oauth2", - }, - { - "type": "literal", - "value": "oidc", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "OAuth scopes requested during authorization", - }, - "isOptional": true, - "name": "scopes", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Whether to skip nonce check (OIDC)", - }, - "isOptional": true, - "name": "skip_nonce_check", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth2 token URL", - }, - "isOptional": true, - "name": "token_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth2 userinfo URL", - }, - "isOptional": true, - "name": "userinfo_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "CustomProviderResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": "CustomOAuthProvider", - "properties": [ - { - "comment": { - "shortText": "Additional client IDs accepted during token validation", - }, - "isOptional": true, - "name": "acceptable_client_ids", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Mapping of provider attributes to Supabase user attributes", - }, - "isOptional": true, - "name": "attribute_mapping", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": "Record", - "type": "record", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "comment": { - "shortText": "Additional parameters sent with the authorization request", - }, - "isOptional": true, - "name": "authorization_params", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": "Record", - "type": "record", - "valueType": { - "name": "string", - "type": "intrinsic", - }, - }, - }, - { - "comment": { - "shortText": "OAuth2 authorization URL", - }, - "isOptional": true, - "name": "authorization_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth client ID", - }, - "name": "client_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Timestamp when the provider was created", - }, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OIDC discovery document (OIDC providers only)", - }, - "isOptional": true, - "name": "discovery_document", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "OIDCDiscoveryDocument", - "properties": [ - { - "comment": { - "shortText": "URL of the authorization endpoint", - }, - "name": "authorization_endpoint", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The issuer identifier", - }, - "name": "issuer", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URL of the JSON Web Key Set", - }, - "name": "jwks_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URL of the revocation endpoint", - }, - "isOptional": true, - "name": "revocation_endpoint", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "List of supported ID token signing algorithms", - }, - "isOptional": true, - "name": "supported_id_token_signing_algs", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "List of supported response types", - }, - "isOptional": true, - "name": "supported_response_types", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "List of supported scopes", - }, - "isOptional": true, - "name": "supported_scopes", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "List of supported subject types", - }, - "isOptional": true, - "name": "supported_subject_types", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "URL of the token endpoint", - }, - "name": "token_endpoint", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URL of the userinfo endpoint", - }, - "isOptional": true, - "name": "userinfo_endpoint", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "type": "literal", - "value": null, - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "OIDC discovery URL", - }, - "isOptional": true, - "name": "discovery_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether email is optional for this provider", - }, - "isOptional": true, - "name": "email_optional", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether the provider is enabled", - }, - "isOptional": true, - "name": "enabled", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Unique identifier (UUID)", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Provider identifier (e.g. \`custom:mycompany\`)", - }, - "name": "identifier", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OIDC issuer URL", - }, - "isOptional": true, - "name": "issuer", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "JWKS URI for token verification", - }, - "isOptional": true, - "name": "jwks_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Human-readable name", - }, - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether PKCE is enabled", - }, - "isOptional": true, - "name": "pkce_enabled", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Provider type", - }, - "name": "provider_type", - "type": { - "name": "CustomProviderType", - "subTypes": [ - { - "type": "literal", - "value": "oauth2", - }, - { - "type": "literal", - "value": "oidc", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "OAuth scopes requested during authorization", - }, - "isOptional": true, - "name": "scopes", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Whether to skip nonce check (OIDC)", - }, - "isOptional": true, - "name": "skip_nonce_check", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth2 token URL", - }, - "isOptional": true, - "name": "token_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Timestamp when the provider was last updated", - }, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth2 userinfo URL", - }, - "isOptional": true, - "name": "userinfo_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminCustomProvidersApi.deleteProvider": { - "comment": { - "shortText": "Deletes a custom provider. - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - }, - "name": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.deleteProvider", - "params": [ - { - "name": "identifier", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "AuthError", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminCustomProvidersApi.getProvider": { - "comment": { - "shortText": "Gets details of a specific custom provider by identifier. - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - }, - "name": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.getProvider", - "params": [ - { - "name": "identifier", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "CustomProviderResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": "CustomOAuthProvider", - "properties": [ - { - "comment": { - "shortText": "Additional client IDs accepted during token validation", - }, - "isOptional": true, - "name": "acceptable_client_ids", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Mapping of provider attributes to Supabase user attributes", - }, - "isOptional": true, - "name": "attribute_mapping", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": "Record", - "type": "record", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "comment": { - "shortText": "Additional parameters sent with the authorization request", - }, - "isOptional": true, - "name": "authorization_params", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": "Record", - "type": "record", - "valueType": { - "name": "string", - "type": "intrinsic", - }, - }, - }, - { - "comment": { - "shortText": "OAuth2 authorization URL", - }, - "isOptional": true, - "name": "authorization_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth client ID", - }, - "name": "client_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Timestamp when the provider was created", - }, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OIDC discovery document (OIDC providers only)", - }, - "isOptional": true, - "name": "discovery_document", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "OIDCDiscoveryDocument", - "properties": [ - { - "comment": { - "shortText": "URL of the authorization endpoint", - }, - "name": "authorization_endpoint", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The issuer identifier", - }, - "name": "issuer", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URL of the JSON Web Key Set", - }, - "name": "jwks_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URL of the revocation endpoint", - }, - "isOptional": true, - "name": "revocation_endpoint", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "List of supported ID token signing algorithms", - }, - "isOptional": true, - "name": "supported_id_token_signing_algs", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "List of supported response types", - }, - "isOptional": true, - "name": "supported_response_types", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "List of supported scopes", - }, - "isOptional": true, - "name": "supported_scopes", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "List of supported subject types", - }, - "isOptional": true, - "name": "supported_subject_types", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "URL of the token endpoint", - }, - "name": "token_endpoint", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URL of the userinfo endpoint", - }, - "isOptional": true, - "name": "userinfo_endpoint", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "type": "literal", - "value": null, - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "OIDC discovery URL", - }, - "isOptional": true, - "name": "discovery_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether email is optional for this provider", - }, - "isOptional": true, - "name": "email_optional", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether the provider is enabled", - }, - "isOptional": true, - "name": "enabled", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Unique identifier (UUID)", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Provider identifier (e.g. \`custom:mycompany\`)", - }, - "name": "identifier", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OIDC issuer URL", - }, - "isOptional": true, - "name": "issuer", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "JWKS URI for token verification", - }, - "isOptional": true, - "name": "jwks_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Human-readable name", - }, - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether PKCE is enabled", - }, - "isOptional": true, - "name": "pkce_enabled", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Provider type", - }, - "name": "provider_type", - "type": { - "name": "CustomProviderType", - "subTypes": [ - { - "type": "literal", - "value": "oauth2", - }, - { - "type": "literal", - "value": "oidc", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "OAuth scopes requested during authorization", - }, - "isOptional": true, - "name": "scopes", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Whether to skip nonce check (OIDC)", - }, - "isOptional": true, - "name": "skip_nonce_check", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth2 token URL", - }, - "isOptional": true, - "name": "token_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Timestamp when the provider was last updated", - }, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth2 userinfo URL", - }, - "isOptional": true, - "name": "userinfo_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminCustomProvidersApi.listProviders": { - "comment": { - "shortText": "Lists all custom providers with optional type filter. - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - }, - "name": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.listProviders", - "params": [ - { - "isOptional": true, - "name": "params", - "type": { - "name": "ListCustomProvidersParams", - "properties": [ - { - "comment": { - "shortText": "Filter by provider type", - }, - "isOptional": true, - "name": "type", - "type": { - "name": "CustomProviderType", - "subTypes": [ - { - "type": "literal", - "value": "oauth2", - }, - { - "type": "literal", - "value": "oidc", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "CustomProviderListResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "providers", - "type": { - "elemType": { - "name": "CustomOAuthProvider", - "properties": [ - { - "comment": { - "shortText": "Additional client IDs accepted during token validation", - }, - "isOptional": true, - "name": "acceptable_client_ids", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Mapping of provider attributes to Supabase user attributes", - }, - "isOptional": true, - "name": "attribute_mapping", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": "Record", - "type": "record", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "comment": { - "shortText": "Additional parameters sent with the authorization request", - }, - "isOptional": true, - "name": "authorization_params", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": "Record", - "type": "record", - "valueType": { - "name": "string", - "type": "intrinsic", - }, - }, - }, - { - "comment": { - "shortText": "OAuth2 authorization URL", - }, - "isOptional": true, - "name": "authorization_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth client ID", - }, - "name": "client_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Timestamp when the provider was created", - }, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OIDC discovery document (OIDC providers only)", - }, - "isOptional": true, - "name": "discovery_document", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "OIDCDiscoveryDocument", - "properties": [ - { - "comment": { - "shortText": "URL of the authorization endpoint", - }, - "name": "authorization_endpoint", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The issuer identifier", - }, - "name": "issuer", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URL of the JSON Web Key Set", - }, - "name": "jwks_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URL of the revocation endpoint", - }, - "isOptional": true, - "name": "revocation_endpoint", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "List of supported ID token signing algorithms", - }, - "isOptional": true, - "name": "supported_id_token_signing_algs", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "List of supported response types", - }, - "isOptional": true, - "name": "supported_response_types", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "List of supported scopes", - }, - "isOptional": true, - "name": "supported_scopes", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "List of supported subject types", - }, - "isOptional": true, - "name": "supported_subject_types", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "URL of the token endpoint", - }, - "name": "token_endpoint", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URL of the userinfo endpoint", - }, - "isOptional": true, - "name": "userinfo_endpoint", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "type": "literal", - "value": null, - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "OIDC discovery URL", - }, - "isOptional": true, - "name": "discovery_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether email is optional for this provider", - }, - "isOptional": true, - "name": "email_optional", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether the provider is enabled", - }, - "isOptional": true, - "name": "enabled", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Unique identifier (UUID)", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Provider identifier (e.g. \`custom:mycompany\`)", - }, - "name": "identifier", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OIDC issuer URL", - }, - "isOptional": true, - "name": "issuer", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "JWKS URI for token verification", - }, - "isOptional": true, - "name": "jwks_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Human-readable name", - }, - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether PKCE is enabled", - }, - "isOptional": true, - "name": "pkce_enabled", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Provider type", - }, - "name": "provider_type", - "type": { - "name": "CustomProviderType", - "subTypes": [ - { - "type": "literal", - "value": "oauth2", - }, - { - "type": "literal", - "value": "oidc", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "OAuth scopes requested during authorization", - }, - "isOptional": true, - "name": "scopes", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Whether to skip nonce check (OIDC)", - }, - "isOptional": true, - "name": "skip_nonce_check", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth2 token URL", - }, - "isOptional": true, - "name": "token_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Timestamp when the provider was last updated", - }, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth2 userinfo URL", - }, - "isOptional": true, - "name": "userinfo_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "providers", - "type": undefined, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminCustomProvidersApi.updateProvider": { - "comment": { - "shortText": "Updates an existing custom provider. - -When \`issuer\` or \`discovery_url\` is changed on an OIDC provider, the server re-fetches and -validates the discovery document before persisting. This may return a validation error -(\`error_code: "validation_failed"\`) if the discovery document is unreachable, invalid, or -the issuer does not match. - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - }, - "name": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.updateProvider", - "params": [ - { - "name": "identifier", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "params", - "type": { - "name": "UpdateCustomProviderParams", - "properties": [ - { - "comment": { - "shortText": "Additional client IDs accepted during token validation", - }, - "isOptional": true, - "name": "acceptable_client_ids", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Mapping of provider attributes to Supabase user attributes", - }, - "isOptional": true, - "name": "attribute_mapping", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": "Record", - "type": "record", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "comment": { - "shortText": "Additional parameters sent with the authorization request", - }, - "isOptional": true, - "name": "authorization_params", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": "Record", - "type": "record", - "valueType": { - "name": "string", - "type": "intrinsic", - }, - }, - }, - { - "comment": { - "shortText": "OAuth2 authorization URL", - }, - "isOptional": true, - "name": "authorization_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth client ID", - }, - "isOptional": true, - "name": "client_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth client secret (write-only, not returned in responses)", - }, - "isOptional": true, - "name": "client_secret", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OIDC discovery URL", - }, - "isOptional": true, - "name": "discovery_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether email is optional for this provider", - }, - "isOptional": true, - "name": "email_optional", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether the provider is enabled", - }, - "isOptional": true, - "name": "enabled", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OIDC issuer URL", - }, - "isOptional": true, - "name": "issuer", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "JWKS URI for token verification", - }, - "isOptional": true, - "name": "jwks_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Human-readable name", - }, - "isOptional": true, - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether PKCE is enabled", - }, - "isOptional": true, - "name": "pkce_enabled", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth scopes requested during authorization", - }, - "isOptional": true, - "name": "scopes", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Whether to skip nonce check (OIDC)", - }, - "isOptional": true, - "name": "skip_nonce_check", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth2 token URL", - }, - "isOptional": true, - "name": "token_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth2 userinfo URL", - }, - "isOptional": true, - "name": "userinfo_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "CustomProviderResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": "CustomOAuthProvider", - "properties": [ - { - "comment": { - "shortText": "Additional client IDs accepted during token validation", - }, - "isOptional": true, - "name": "acceptable_client_ids", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Mapping of provider attributes to Supabase user attributes", - }, - "isOptional": true, - "name": "attribute_mapping", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": "Record", - "type": "record", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "comment": { - "shortText": "Additional parameters sent with the authorization request", - }, - "isOptional": true, - "name": "authorization_params", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": "Record", - "type": "record", - "valueType": { - "name": "string", - "type": "intrinsic", - }, - }, - }, - { - "comment": { - "shortText": "OAuth2 authorization URL", - }, - "isOptional": true, - "name": "authorization_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth client ID", - }, - "name": "client_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Timestamp when the provider was created", - }, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OIDC discovery document (OIDC providers only)", - }, - "isOptional": true, - "name": "discovery_document", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "OIDCDiscoveryDocument", - "properties": [ - { - "comment": { - "shortText": "URL of the authorization endpoint", - }, - "name": "authorization_endpoint", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The issuer identifier", - }, - "name": "issuer", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URL of the JSON Web Key Set", - }, - "name": "jwks_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URL of the revocation endpoint", - }, - "isOptional": true, - "name": "revocation_endpoint", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "List of supported ID token signing algorithms", - }, - "isOptional": true, - "name": "supported_id_token_signing_algs", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "List of supported response types", - }, - "isOptional": true, - "name": "supported_response_types", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "List of supported scopes", - }, - "isOptional": true, - "name": "supported_scopes", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "List of supported subject types", - }, - "isOptional": true, - "name": "supported_subject_types", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "URL of the token endpoint", - }, - "name": "token_endpoint", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URL of the userinfo endpoint", - }, - "isOptional": true, - "name": "userinfo_endpoint", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "type": "literal", - "value": null, - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "OIDC discovery URL", - }, - "isOptional": true, - "name": "discovery_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether email is optional for this provider", - }, - "isOptional": true, - "name": "email_optional", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether the provider is enabled", - }, - "isOptional": true, - "name": "enabled", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Unique identifier (UUID)", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Provider identifier (e.g. \`custom:mycompany\`)", - }, - "name": "identifier", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OIDC issuer URL", - }, - "isOptional": true, - "name": "issuer", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "JWKS URI for token verification", - }, - "isOptional": true, - "name": "jwks_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Human-readable name", - }, - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Whether PKCE is enabled", - }, - "isOptional": true, - "name": "pkce_enabled", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Provider type", - }, - "name": "provider_type", - "type": { - "name": "CustomProviderType", - "subTypes": [ - { - "type": "literal", - "value": "oauth2", - }, - { - "type": "literal", - "value": "oidc", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "OAuth scopes requested during authorization", - }, - "isOptional": true, - "name": "scopes", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Whether to skip nonce check (OIDC)", - }, - "isOptional": true, - "name": "skip_nonce_check", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth2 token URL", - }, - "isOptional": true, - "name": "token_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Timestamp when the provider was last updated", - }, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "OAuth2 userinfo URL", - }, - "isOptional": true, - "name": "userinfo_url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminMFAApi.deleteFactor": { - "comment": { - "examples": [ - { - "code": "\`\`\`js -const { data, error } = await supabase.auth.admin.mfa.deleteFactor({ - id: '34e770dd-9ff9-416c-87fa-43b31d7ef225', - userId: 'a89baba7-b1b7-440f-b4bb-91026967f66b', -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "delete-a-factor-for-a-user", - "name": "Delete a factor for a user", - "response": "\`\`\`json -{ - data: { - id: '34e770dd-9ff9-416c-87fa-43b31d7ef225' - }, - error: null -} -\`\`\`", - }, - ], - "shortText": "Deletes a factor on a user. This will log the user out of all active -sessions if the deleted factor was verified.", - }, - "name": "@supabase/auth-js.GoTrueAdminMFAApi.deleteFactor", - "params": [ - { - "name": "params", - "type": { - "name": "AuthMFAAdminDeleteFactorParams", - "properties": [ - { - "comment": { - "shortText": "ID of the MFA factor to delete.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the user whose factor is being deleted.", - }, - "name": "userId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "AuthMFAAdminDeleteFactorResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "comment": { - "shortText": "ID of the factor that was successfully deleted.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminMFAApi.listFactors": { - "comment": { - "examples": [ - { - "code": "\`\`\`js -const { data, error } = await supabase.auth.admin.mfa.listFactors() -\`\`\`", - "data": undefined, - "description": undefined, - "id": "list-all-factors-for-a-user", - "name": "List all factors for a user", - "response": "\`\`\`json -{ - data: { - factors: Factor[ - { - id: '', - friendly_name: 'Auth App Factor', - factor_type: 'totp', - status: 'verified', - created_at: '2024-01-01T00:00:00Z', - updated_at: '2024-01-01T00:00:00Z' - } - ] - }, - error: null -} -\`\`\`", - }, - ], - "shortText": "Lists all factors associated to a user.", - }, - "name": "@supabase/auth-js.GoTrueAdminMFAApi.listFactors", - "params": [ - { - "name": "params", - "type": { - "name": "AuthMFAAdminListFactorsParams", - "properties": [ - { - "comment": { - "shortText": "ID of the user.", - }, - "name": "userId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "AuthMFAAdminListFactorsResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "comment": { - "shortText": "All factors attached to the user.", - }, - "name": "factors", - "type": { - "elemType": { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": "Type", - "type": "nameOnly", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": "Status", - "type": "nameOnly", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminOAuthApi.createClient": { - "comment": { - "shortText": "Creates a new OAuth client. -Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - }, - "name": "@supabase/auth-js.GoTrueAdminOAuthApi.createClient", - "params": [ - { - "name": "params", - "type": { - "name": "CreateOAuthClientParams", - "properties": [ - { - "comment": { - "shortText": "Human-readable name of the OAuth client", - }, - "name": "client_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URI of the OAuth client", - }, - "isOptional": true, - "name": "client_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Array of allowed grant types (optional, defaults to authorization_code and refresh_token)", - }, - "isOptional": true, - "name": "grant_types", - "type": { - "elemType": { - "name": "OAuthClientGrantType", - "subTypes": [ - { - "type": "literal", - "value": "authorization_code", - }, - { - "type": "literal", - "value": "refresh_token", - }, - undefined, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Array of allowed redirect URIs", - }, - "name": "redirect_uris", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Array of allowed response types (optional, defaults to code)", - }, - "isOptional": true, - "name": "response_types", - "type": { - "elemType": { - "name": "OAuthClientResponseType", - "type": "literal", - "value": "code", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Scope of the OAuth client", - }, - "isOptional": true, - "name": "scope", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Token endpoint authentication method (defaults to server default if not specified)", - }, - "isOptional": true, - "name": "token_endpoint_auth_method", - "type": { - "name": "OAuthClientTokenEndpointAuthMethod", - "subTypes": [ - { - "type": "literal", - "value": "none", - }, - { - "type": "literal", - "value": "client_secret_basic", - }, - { - "type": "literal", - "value": "client_secret_post", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "OAuthClientResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": "OAuthClient", - "properties": [ - { - "comment": { - "shortText": "Unique identifier for the OAuth client", - }, - "name": "client_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Human-readable name of the OAuth client", - }, - "name": "client_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Client secret (only returned on registration and regeneration)", - }, - "isOptional": true, - "name": "client_secret", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of OAuth client", - }, - "name": "client_type", - "type": { - "name": "OAuthClientType", - "subTypes": [ - { - "type": "literal", - "value": "public", - }, - { - "type": "literal", - "value": "confidential", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "URI of the OAuth client", - }, - "isOptional": true, - "name": "client_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Timestamp when the client was created", - }, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Array of allowed grant types", - }, - "name": "grant_types", - "type": { - "elemType": { - "name": "OAuthClientGrantType", - "subTypes": [ - { - "type": "literal", - "value": "authorization_code", - }, - { - "type": "literal", - "value": "refresh_token", - }, - undefined, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "URI of the OAuth client's logo", - }, - "isOptional": true, - "name": "logo_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Array of allowed redirect URIs", - }, - "name": "redirect_uris", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Registration type of the client", - }, - "name": "registration_type", - "type": { - "name": "OAuthClientRegistrationType", - "subTypes": [ - { - "type": "literal", - "value": "dynamic", - }, - { - "type": "literal", - "value": "manual", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Array of allowed response types", - }, - "name": "response_types", - "type": { - "elemType": { - "name": "OAuthClientResponseType", - "type": "literal", - "value": "code", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Scope of the OAuth client", - }, - "isOptional": true, - "name": "scope", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Token endpoint authentication method", - }, - "name": "token_endpoint_auth_method", - "type": { - "name": "OAuthClientTokenEndpointAuthMethod", - "subTypes": [ - { - "type": "literal", - "value": "none", - }, - { - "type": "literal", - "value": "client_secret_basic", - }, - { - "type": "literal", - "value": "client_secret_post", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Timestamp when the client was last updated", - }, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminOAuthApi.deleteClient": { - "comment": { - "shortText": "Deletes an OAuth client. -Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - }, - "name": "@supabase/auth-js.GoTrueAdminOAuthApi.deleteClient", - "params": [ - { - "name": "clientId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "AuthError", - "type": "nameOnly", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminOAuthApi.getClient": { - "comment": { - "shortText": "Gets details of a specific OAuth client. -Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - }, - "name": "@supabase/auth-js.GoTrueAdminOAuthApi.getClient", - "params": [ - { - "name": "clientId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "OAuthClientResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": "OAuthClient", - "properties": [ - { - "comment": { - "shortText": "Unique identifier for the OAuth client", - }, - "name": "client_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Human-readable name of the OAuth client", - }, - "name": "client_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Client secret (only returned on registration and regeneration)", - }, - "isOptional": true, - "name": "client_secret", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of OAuth client", - }, - "name": "client_type", - "type": { - "name": "OAuthClientType", - "subTypes": [ - { - "type": "literal", - "value": "public", - }, - { - "type": "literal", - "value": "confidential", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "URI of the OAuth client", - }, - "isOptional": true, - "name": "client_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Timestamp when the client was created", - }, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Array of allowed grant types", - }, - "name": "grant_types", - "type": { - "elemType": { - "name": "OAuthClientGrantType", - "subTypes": [ - { - "type": "literal", - "value": "authorization_code", - }, - { - "type": "literal", - "value": "refresh_token", - }, - undefined, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "URI of the OAuth client's logo", - }, - "isOptional": true, - "name": "logo_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Array of allowed redirect URIs", - }, - "name": "redirect_uris", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Registration type of the client", - }, - "name": "registration_type", - "type": { - "name": "OAuthClientRegistrationType", - "subTypes": [ - { - "type": "literal", - "value": "dynamic", - }, - { - "type": "literal", - "value": "manual", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Array of allowed response types", - }, - "name": "response_types", - "type": { - "elemType": { - "name": "OAuthClientResponseType", - "type": "literal", - "value": "code", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Scope of the OAuth client", - }, - "isOptional": true, - "name": "scope", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Token endpoint authentication method", - }, - "name": "token_endpoint_auth_method", - "type": { - "name": "OAuthClientTokenEndpointAuthMethod", - "subTypes": [ - { - "type": "literal", - "value": "none", - }, - { - "type": "literal", - "value": "client_secret_basic", - }, - { - "type": "literal", - "value": "client_secret_post", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Timestamp when the client was last updated", - }, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminOAuthApi.listClients": { - "comment": { - "shortText": "Lists all OAuth clients with optional pagination. -Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - }, - "name": "@supabase/auth-js.GoTrueAdminOAuthApi.listClients", - "params": [ - { - "isOptional": true, - "name": "params", - "type": { - "name": "PageParams", - "properties": [ - { - "comment": { - "shortText": "The page number", - }, - "isOptional": true, - "name": "page", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Number of items returned per page", - }, - "isOptional": true, - "name": "perPage", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "OAuthClientListResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": undefined, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "clients", - "type": undefined, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminOAuthApi.regenerateClientSecret": { - "comment": { - "shortText": "Regenerates the secret for an OAuth client. -Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - }, - "name": "@supabase/auth-js.GoTrueAdminOAuthApi.regenerateClientSecret", - "params": [ - { - "name": "clientId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "OAuthClientResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": "OAuthClient", - "properties": [ - { - "comment": { - "shortText": "Unique identifier for the OAuth client", - }, - "name": "client_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Human-readable name of the OAuth client", - }, - "name": "client_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Client secret (only returned on registration and regeneration)", - }, - "isOptional": true, - "name": "client_secret", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of OAuth client", - }, - "name": "client_type", - "type": { - "name": "OAuthClientType", - "subTypes": [ - { - "type": "literal", - "value": "public", - }, - { - "type": "literal", - "value": "confidential", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "URI of the OAuth client", - }, - "isOptional": true, - "name": "client_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Timestamp when the client was created", - }, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Array of allowed grant types", - }, - "name": "grant_types", - "type": { - "elemType": { - "name": "OAuthClientGrantType", - "subTypes": [ - { - "type": "literal", - "value": "authorization_code", - }, - { - "type": "literal", - "value": "refresh_token", - }, - undefined, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "URI of the OAuth client's logo", - }, - "isOptional": true, - "name": "logo_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Array of allowed redirect URIs", - }, - "name": "redirect_uris", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Registration type of the client", - }, - "name": "registration_type", - "type": { - "name": "OAuthClientRegistrationType", - "subTypes": [ - { - "type": "literal", - "value": "dynamic", - }, - { - "type": "literal", - "value": "manual", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Array of allowed response types", - }, - "name": "response_types", - "type": { - "elemType": { - "name": "OAuthClientResponseType", - "type": "literal", - "value": "code", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Scope of the OAuth client", - }, - "isOptional": true, - "name": "scope", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Token endpoint authentication method", - }, - "name": "token_endpoint_auth_method", - "type": { - "name": "OAuthClientTokenEndpointAuthMethod", - "subTypes": [ - { - "type": "literal", - "value": "none", - }, - { - "type": "literal", - "value": "client_secret_basic", - }, - { - "type": "literal", - "value": "client_secret_post", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Timestamp when the client was last updated", - }, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminOAuthApi.updateClient": { - "comment": { - "shortText": "Updates an existing OAuth client. -Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - }, - "name": "@supabase/auth-js.GoTrueAdminOAuthApi.updateClient", - "params": [ - { - "name": "clientId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "params", - "type": { - "name": "UpdateOAuthClientParams", - "properties": [ - { - "comment": { - "shortText": "Human-readable name of the OAuth client", - }, - "isOptional": true, - "name": "client_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "URI of the OAuth client", - }, - "isOptional": true, - "name": "client_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Array of allowed grant types", - }, - "isOptional": true, - "name": "grant_types", - "type": { - "elemType": { - "name": "OAuthClientGrantType", - "subTypes": [ - { - "type": "literal", - "value": "authorization_code", - }, - { - "type": "literal", - "value": "refresh_token", - }, - undefined, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "URI of the OAuth client's logo", - }, - "isOptional": true, - "name": "logo_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Array of allowed redirect URIs", - }, - "isOptional": true, - "name": "redirect_uris", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Token endpoint authentication method", - }, - "isOptional": true, - "name": "token_endpoint_auth_method", - "type": { - "name": "OAuthClientTokenEndpointAuthMethod", - "subTypes": [ - { - "type": "literal", - "value": "none", - }, - { - "type": "literal", - "value": "client_secret_basic", - }, - { - "type": "literal", - "value": "client_secret_post", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "OAuthClientResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": "OAuthClient", - "properties": [ - { - "comment": { - "shortText": "Unique identifier for the OAuth client", - }, - "name": "client_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Human-readable name of the OAuth client", - }, - "name": "client_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Client secret (only returned on registration and regeneration)", - }, - "isOptional": true, - "name": "client_secret", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of OAuth client", - }, - "name": "client_type", - "type": { - "name": "OAuthClientType", - "subTypes": [ - { - "type": "literal", - "value": "public", - }, - { - "type": "literal", - "value": "confidential", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "URI of the OAuth client", - }, - "isOptional": true, - "name": "client_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Timestamp when the client was created", - }, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Array of allowed grant types", - }, - "name": "grant_types", - "type": { - "elemType": { - "name": "OAuthClientGrantType", - "subTypes": [ - { - "type": "literal", - "value": "authorization_code", - }, - { - "type": "literal", - "value": "refresh_token", - }, - undefined, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "URI of the OAuth client's logo", - }, - "isOptional": true, - "name": "logo_uri", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Array of allowed redirect URIs", - }, - "name": "redirect_uris", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Registration type of the client", - }, - "name": "registration_type", - "type": { - "name": "OAuthClientRegistrationType", - "subTypes": [ - { - "type": "literal", - "value": "dynamic", - }, - { - "type": "literal", - "value": "manual", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Array of allowed response types", - }, - "name": "response_types", - "type": { - "elemType": { - "name": "OAuthClientResponseType", - "type": "literal", - "value": "code", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "comment": { - "shortText": "Scope of the OAuth client", - }, - "isOptional": true, - "name": "scope", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Token endpoint authentication method", - }, - "name": "token_endpoint_auth_method", - "type": { - "name": "OAuthClientTokenEndpointAuthMethod", - "subTypes": [ - { - "type": "literal", - "value": "none", - }, - { - "type": "literal", - "value": "client_secret_basic", - }, - { - "type": "literal", - "value": "client_secret_post", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Timestamp when the client was last updated", - }, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminPasskeyApi.deletePasskey": { - "comment": { - "shortText": "Deletes a specific passkey for a specific user. - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - }, - "name": "@supabase/auth-js.GoTrueAdminPasskeyApi.deletePasskey", - "params": [ - { - "name": "params", - "type": { - "name": "AuthPasskeyAdminDeleteParams", - "properties": [ - { - "name": "passkeyId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "userId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "AuthPasskeyDeleteResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueAdminPasskeyApi.listPasskeys": { - "comment": { - "shortText": "Lists all passkeys registered for a specific user. - -This function should only be called on a server. Never expose your \`service_role\` key in the browser.", - }, - "name": "@supabase/auth-js.GoTrueAdminPasskeyApi.listPasskeys", - "params": [ - { - "name": "params", - "type": { - "name": "AuthPasskeyAdminListParams", - "properties": [ - { - "name": "userId", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "AuthPasskeyListResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "elemType": { - "name": "PasskeyListItem", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_used_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": undefined, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueClient.constructor": { - "comment": { - "examples": [ - { - "code": "\`\`\`ts -import { createClient } from '@supabase/supabase-js' - -const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key') -const { data, error } = await supabase.auth.getUser() -\`\`\`", - "data": undefined, - "description": undefined, - "id": "using-supabase-js-recommended", - "name": "Using supabase-js (recommended)", - "response": undefined, - }, - { - "code": "\`\`\`ts -import { GoTrueClient } from '@supabase/auth-js' - -const auth = new GoTrueClient({ - url: 'https://xyzcompany.supabase.co/auth/v1', - headers: { apikey: 'your-publishable-key' }, - storageKey: 'supabase-auth', -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "standalone-import-for-bundle-sensitive-environments", - "name": "Standalone import for bundle-sensitive environments", - "response": undefined, - }, - ], - "shortText": "Create a new client for use in the browser.", - }, - "name": "@supabase/auth-js.GoTrueClient.constructor", - "params": [ - { - "name": "options", - "type": { - "name": "GoTrueClientOptions", - "properties": [ - { - "isOptional": true, - "name": "autoRefreshToken", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "debug", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "boolean", - "type": "intrinsic", - }, - { - "comment": undefined, - "name": Symbol(anonymous), - "params": [ - { - "name": "message", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "args", - "type": { - "elemType": { - "name": "any", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "ret": { - "type": { - "name": "void", - "type": "intrinsic", - }, - }, - "type": "function", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "examples": [ - { - "code": "\`\`\`ts -detectSessionInUrl: (url, params) => { - // Ignore Facebook OAuth redirects - if (url.pathname === '/facebook/redirect') return false - // Use default detection for other URLs - return Boolean(params.access_token || params.error_description) -} -\`\`\`", - "data": undefined, - "description": undefined, - "id": "example-1", - "name": "Example 1", - "response": undefined, - }, - ], - "shortText": "Set to "true" if you want to automatically detect OAuth grants in the URL and sign in the user. -Set to "false" to disable automatic detection. -Set to a function to provide custom logic for determining if a URL contains a Supabase auth callback. -The function receives the current URL and parsed parameters, and should return true if the URL -should be processed as a Supabase auth callback, or false to ignore it. - -This is useful when your app uses other OAuth providers (e.g., Facebook Login) that also return -access_token in the URL fragment, which would otherwise be incorrectly intercepted by Supabase Auth.", - }, - "isOptional": true, - "name": "detectSessionInUrl", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "boolean", - "type": "intrinsic", - }, - { - "comment": undefined, - "name": Symbol(anonymous), - "params": [ - { - "name": "url", - "type": { - "name": "URL", - "type": "nameOnly", - }, - }, - { - "name": "params", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "string", - "type": "intrinsic", - }, - }, - }, - ], - "ret": { - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - "type": "function", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Opt-in flags for experimental features. These APIs may change without -notice and are disabled by default.", - "tags": [ - { - "tag": "experimental", - "text": "", - }, - ], - }, - "isOptional": true, - "name": "experimental", - "type": { - "name": "ExperimentalFeatureFlags", - "properties": [ - { - "comment": { - "shortText": "Enables passkey support: - - \`auth.signInWithPasskey()\`, \`auth.registerPasskey()\` - - \`auth.passkey.*\` - - \`auth.admin.passkey.*\` - -Defaults to \`false\`. Calling any passkey method while this flag is -disabled throws a descriptive error at call time.", - }, - "isOptional": true, - "name": "passkey", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "isOptional": true, - "name": "fetch", - "type": { - "name": "Fetch", - "type": "nameOnly", - }, - }, - { - "isOptional": true, - "name": "flowType", - "type": { - "name": "AuthFlowType", - "subTypes": [ - { - "type": "literal", - "value": "implicit", - }, - { - "type": "literal", - "value": "pkce", - }, - undefined, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Set to "true" if there is a custom authorization header set globally.", - "tags": [ - { - "tag": "experimental", - "text": "", - }, - ], - }, - "isOptional": true, - "name": "hasCustomAuthorizationHeader", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "headers", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "string", - "type": "intrinsic", - }, - }, - }, - { - "comment": { - "shortText": "Provide your own locking mechanism based on the environment. By default -the client coordinates refreshes itself (single-flight via -\`refreshingDeferred\` + commit guard) and relies on the GoTrue server to -resolve cross-tab refresh races. Passing a custom lock opts into a -legacy path that wraps every auth operation in your supplied lock — this -path is preserved for backwards compatibility (typically React Native -\`processLock\` or Node multi-process setups).", - }, - "isOptional": true, - "name": "lock", - "type": { - "comment": undefined, - "name": "LockFunc", - "params": [ - { - "comment": { - "shortText": "Name of the lock to be acquired.", - }, - "name": "name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "If negative, no timeout should occur. If positive it - should throw an Error with an \`isAcquireTimeout\` - property set to true if the operation fails to be - acquired after this much time (ms).", - }, - "name": "acquireTimeout", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The operation to execute when the lock is acquired.", - }, - "name": "fn", - "type": { - "comment": undefined, - "name": Symbol(anonymous), - "params": [], - "ret": { - "type": { - "awaited": { - "name": "R", - "type": "nameOnly", - }, - "name": "Promise", - "type": "promise", - }, - }, - "type": "function", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "R", - "type": "nameOnly", - }, - "name": "Promise", - "type": "promise", - }, - }, - "type": "function", - }, - }, - { - "comment": { - "shortText": "The maximum time in milliseconds to wait for acquiring the custom lock -supplied via the \`lock\` option. Only consulted when a custom \`lock\` is -passed — the default lockless path doesn't use this timeout.", - }, - "isOptional": true, - "name": "lockAcquireTimeout", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "persistSession", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "If true, skips automatic initialization in constructor. Useful for SSR -contexts where initialization timing must be controlled to prevent race -conditions with HTTP response generation.", - }, - "isOptional": true, - "name": "skipAutoInitialize", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "storage", - "type": { - "name": "SupportedStorage", - "type": "nameOnly", - }, - }, - { - "isOptional": true, - "name": "storageKey", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "If there is an error with the query, throwOnError will reject the promise by -throwing the error instead of returning it as part of a successful response.", - }, - "isOptional": true, - "name": "throwOnError", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Stores the user object in a separate storage location from the rest of the session data. When non-null, \`storage\` will only store a JSON object containing the access and refresh token and some adjacent metadata, while \`userStorage\` will only contain the user object under the key \`storageKey + '-user'\`. - -When this option is set and cookie storage is used, \`getSession()\` and other functions that load a session from the cookie store might not return back a user. It's very important to always use \`getUser()\` to fetch a user object in those scenarios.", - "tags": [ - { - "tag": "experimental", - "text": "", - }, - ], - }, - "isOptional": true, - "name": "userStorage", - "type": { - "name": "SupportedStorage", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "name": "GoTrueClient", - "type": "nameOnly", - }, - }, - }, - "@supabase/auth-js.GoTrueClient.dispose": { - "comment": { - "examples": [ - { - "code": "\`\`\`ts -useEffect(() => { - const client = createClient(...) - return () => { client.auth.dispose() } -}, []) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "cleanup-on-react-unmount", - "name": "Cleanup on React unmount", - "response": undefined, - }, - ], - "shortText": "Tears down the client's background work: stops the auto-refresh interval, -removes the \`visibilitychange\` listener, closes the cross-tab -\`BroadcastChannel\`, and clears registered \`onAuthStateChange\` subscribers. - -Call this from cleanup hooks when the client is being replaced before -its JS realm is destroyed. React Strict Mode and HMR are the common -cases. Any in-flight \`fetch\` calls continue to completion and may still -write to storage; dispose doesn't abort them or erase storage. - -Lifecycle caveat: because in-flight refreshes are not aborted, a -disposed instance can still persist a rotated session to storage after -\`dispose()\` returns. A subsequent \`createClient\` against the same -\`storageKey\` will pick up that session on its next read. If you need -strict isolation between client lifecycles, await any pending auth -operation before calling \`dispose()\` (or change the \`storageKey\` for -the replacement client). - -Safe to call repeatedly.", - }, - "name": "@supabase/auth-js.GoTrueClient.dispose", - "params": [], - "ret": { - "type": { - "awaited": { - "name": "void", - "type": "intrinsic", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueClient.exchangeCodeForSession": { - "comment": { - "examples": [ - { - "code": "\`\`\`js -supabase.auth.exchangeCodeForSession('34e770dd-9ff9-416c-87fa-43b31d7ef225') -\`\`\`", - "data": undefined, - "description": undefined, - "id": "exchange-auth-code", - "name": "Exchange Auth Code", - "response": "\`\`\`json -{ - "data": { - session: { - access_token: '', - token_type: 'bearer', - expires_in: 3600, - expires_at: 1700000000, - refresh_token: '', - user: { - id: '11111111-1111-1111-1111-111111111111', - aud: 'authenticated', - role: 'authenticated', - email: 'example@email.com' - email_confirmed_at: '2024-01-01T00:00:00Z', - phone: '', - confirmation_sent_at: '2024-01-01T00:00:00Z', - confirmed_at: '2024-01-01T00:00:00Z', - last_sign_in_at: '2024-01-01T00:00:00Z', - app_metadata: { - "provider": "email", - "providers": [ - "email", - "" - ] - }, - user_metadata: { - email: 'email@email.com', - email_verified: true, - full_name: 'User Name', - iss: '', - name: 'User Name', - phone_verified: false, - provider_id: '', - sub: '' - }, - identities: [ - { - "identity_id": "22222222-2222-2222-2222-222222222222", - "id": "11111111-1111-1111-1111-111111111111", - "user_id": "11111111-1111-1111-1111-111111111111", - "identity_data": { - "email": "example@email.com", - "email_verified": false, - "phone_verified": false, - "sub": "11111111-1111-1111-1111-111111111111" - }, - "provider": "email", - "last_sign_in_at": "2024-01-01T00:00:00Z", - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "email": "email@example.com" - }, - { - "identity_id": "33333333-3333-3333-3333-333333333333", - "id": "", - "user_id": "", - "identity_data": { - "email": "example@email.com", - "email_verified": true, - "full_name": "User Name", - "iss": "", - "name": "User Name", - "phone_verified": false, - "provider_id": "", - "sub": "" - }, - "provider": "", - "last_sign_in_at": "2024-01-01T00:00:00Z", - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "email": "example@email.com" - } - ], - created_at: '2024-01-01T00:00:00Z', - updated_at: '2024-01-01T00:00:00Z', - is_anonymous: false - }, - provider_token: '', - provider_refresh_token: '' - }, - user: { - id: '11111111-1111-1111-1111-111111111111', - aud: 'authenticated', - role: 'authenticated', - email: 'example@email.com', - email_confirmed_at: '2024-01-01T00:00:00Z', - phone: '', - confirmation_sent_at: '2024-01-01T00:00:00Z', - confirmed_at: '2024-01-01T00:00:00Z', - last_sign_in_at: '2024-01-01T00:00:00Z', - app_metadata: { - provider: 'email', - providers: [ - "email", - "" - ] - }, - user_metadata: { - email: 'email@email.com', - email_verified: true, - full_name: 'User Name', - iss: '', - name: 'User Name', - phone_verified: false, - provider_id: '', - sub: '' - }, - identities: [ - { - "identity_id": "22222222-2222-2222-2222-222222222222", - "id": "11111111-1111-1111-1111-111111111111", - "user_id": "11111111-1111-1111-1111-111111111111", - "identity_data": { - "email": "example@email.com", - "email_verified": false, - "phone_verified": false, - "sub": "11111111-1111-1111-1111-111111111111" - }, - "provider": "email", - "last_sign_in_at": "2024-01-01T00:00:00Z", - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "email": "email@example.com" - }, - { - "identity_id": "33333333-3333-3333-3333-333333333333", - "id": "", - "user_id": "", - "identity_data": { - "email": "example@email.com", - "email_verified": true, - "full_name": "User Name", - "iss": "", - "name": "User Name", - "phone_verified": false, - "provider_id": "", - "sub": "" - }, - "provider": "", - "last_sign_in_at": "2024-01-01T00:00:00Z", - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "email": "example@email.com" - } - ], - created_at: '2024-01-01T00:00:00Z', - updated_at: '2024-01-01T00:00:00Z', - is_anonymous: false - }, - redirectType: null - }, - "error": null -} -\`\`\`", - }, - ], - "shortText": "Log in an existing user by exchanging an Auth Code issued during the PKCE flow.", - "text": "- Used when \`flowType\` is set to \`pkce\` in client options.", - }, - "name": "@supabase/auth-js.GoTrueClient.exchangeCodeForSession", - "params": [ - { - "name": "authCode", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "AuthTokenResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "session", - "type": { - "name": "Session", - "properties": [ - { - "comment": { - "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value.", - }, - "name": "access_token", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed.", - }, - "isOptional": true, - "name": "expires_at", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed.", - }, - "name": "expires_in", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API. -Not all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token.", - }, - "isOptional": true, - "name": "provider_refresh_token", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "string", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used.", - }, - "isOptional": true, - "name": "provider_token", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "string", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "A one-time used refresh token that never expires.", - }, - "name": "refresh_token", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "token_type", - "type": { - "type": "literal", - "value": "bearer", - }, - }, - { - "comment": { - "shortText": "When using a separate user storage, accessing properties of this object will throw an error.", - }, - "name": "user", - "type": { - "name": "User", - "properties": [ - { - "isOptional": true, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "banned_until", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmation_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "deleted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_change_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "factors", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "invited_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_sso_user", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "recovery_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "user", - "type": { - "name": "User", - "properties": [ - { - "isOptional": true, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "banned_until", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmation_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "deleted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_change_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "factors", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "invited_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_sso_user", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "recovery_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "properties": [ - { - "name": "session", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "user", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueClient.getClaims": { - "comment": { - "examples": [ - { - "code": "\`\`\`js -const { data, error } = await supabase.auth.getClaims() -\`\`\`", - "data": undefined, - "description": undefined, - "id": "get-jwt-claims-header-and-signature", - "name": "Get JWT claims, header and signature", - "response": "\`\`\`json -{ - "data": { - "claims": { - "aal": "aal1", - "amr": [{ - "method": "email", - "timestamp": 1715766000 - }], - "app_metadata": {}, - "aud": "authenticated", - "email": "example@email.com", - "exp": 1715769600, - "iat": 1715766000, - "is_anonymous": false, - "iss": "https://project-id.supabase.co/auth/v1", - "phone": "+13334445555", - "role": "authenticated", - "session_id": "11111111-1111-1111-1111-111111111111", - "sub": "11111111-1111-1111-1111-111111111111", - "user_metadata": {} - }, - "header": { - "alg": "RS256", - "typ": "JWT", - "kid": "11111111-1111-1111-1111-111111111111" - }, - "signature": [/** Uint8Array */], - }, - "error": null -} -\`\`\`", - }, - ], - "shortText": "Extracts the JWT claims present in the access token by first verifying the -JWT against the server's JSON Web Key Set endpoint -\`/.well-known/jwks.json\` which is often cached, resulting in significantly -faster responses. Prefer this method over #getUser which always -sends a request to the Auth server for each JWT. - -If the project is not using an asymmetric JWT signing key (like ECC or -RSA) it always sends a request to the Auth server (similar to #getUser) to verify the JWT.", - "text": "- Parses the user's [access token](/docs/guides/auth/sessions#access-token-jwt-claims) as a [JSON Web Token (JWT)](/docs/guides/auth/jwts) and returns its components if valid and not expired. -- If your project is using asymmetric JWT signing keys, then the verification is done locally usually without a network request using the [WebCrypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API). -- A network request is sent to your project's JWT signing key discovery endpoint \`https://project-id.supabase.co/auth/v1/.well-known/jwks.json\`, which is cached locally. If your environment is ephemeral, such as a Lambda function that is destroyed after every request, a network request will be sent for each new invocation. Supabase provides a network-edge cache providing fast responses for these situations. -- If the user's access token is about to expire when calling this function, the user's session will first be refreshed before validating the JWT. -- If your project is using a symmetric secret to sign the JWT, it always sends a request similar to \`getUser()\` to validate the JWT at the server before returning the decoded token. This is also used if the WebCrypto API is not available in the environment. Make sure you polyfill it in such situations. -- The returned claims can be customized per project using the [Custom Access Token Hook](/docs/guides/auth/auth-hooks/custom-access-token-hook).", - }, - "name": "@supabase/auth-js.GoTrueClient.getClaims", - "params": [ - { - "comment": { - "shortText": "An optional specific JWT you wish to verify, not the one you - can obtain from #getSession.", - }, - "isOptional": true, - "name": "jwt", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Various additional options that allow you to customize the - behavior of this method.", - }, - "name": "options", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "comment": { - "shortText": "If set to \`true\` the \`exp\` claim will not be validated against the current time.", - }, - "isOptional": true, - "name": "allowExpired", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "If set, this JSON Web Key Set is going to have precedence over the cached value available on the server.", - }, - "isOptional": true, - "name": "jwks", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "keys", - "type": { - "elemType": { - "name": "JWK", - "properties": [ - { - "isOptional": true, - "name": "alg", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "key_ops", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "kid", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "kty", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - undefined, - { - "type": "literal", - "value": "RSA", - }, - { - "type": "literal", - "value": "EC", - }, - { - "type": "literal", - "value": "oct", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "comment": { - "shortText": "", - }, - "isOptional": true, - "name": "keys", - "type": { - "elemType": { - "name": "JWK", - "properties": [ - { - "isOptional": true, - "name": "alg", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "key_ops", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "kid", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "kty", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - undefined, - { - "type": "literal", - "value": "RSA", - }, - { - "type": "literal", - "value": "EC", - }, - { - "type": "literal", - "value": "oct", - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "claims", - "type": { - "name": "JwtPayload", - "properties": [ - { - "name": "aal", - "type": { - "name": "AuthenticatorAssuranceLevels", - "subTypes": [ - { - "type": "literal", - "value": "aal1", - }, - { - "type": "literal", - "value": "aal2", - }, - undefined, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Authentication Method References. -Supports both RFC-8176 compliant format (string[]) and detailed format (AMREntry[]). -- String format: ['password', 'otp'] - RFC-8176 compliant -- Object format: [{ method: 'password', timestamp: 1234567890 }] - includes timestamps", - }, - "isOptional": true, - "name": "amr", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - { - "elemType": { - "name": "AMREntry", - "properties": [ - { - "comment": { - "shortText": "Authentication method name.", - }, - "name": "method", - "type": { - "name": "AMRMethod", - "subTypes": [ - { - "name": "['number']", - "type": "nameOnly", - }, - undefined, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Timestamp when the method was successfully used. Represents number of -seconds since 1st January 1970 (UNIX epoch) in UTC.", - }, - "name": "timestamp", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - ], - "type": "union", - }, - }, - { - "isOptional": true, - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "string", - "type": "intrinsic", - }, - { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - ], - "type": "union", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "exp", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "name": "iat", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "name": "iss", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "jti", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "nbf", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "ref", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "session_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "sub", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "header", - "type": { - "name": "JwtHeader", - "properties": [ - { - "name": "alg", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "RS256", - }, - { - "type": "literal", - "value": "ES256", - }, - { - "type": "literal", - "value": "HS256", - }, - undefined, - ], - "type": "union", - }, - }, - { - "name": "kid", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "typ", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "signature", - "type": { - "name": "Uint8Array", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueClient.getSession": { - "comment": { - "examples": [ - { - "code": "\`\`\`js -const { data, error } = await supabase.auth.getSession() -\`\`\`", - "data": undefined, - "description": undefined, - "id": "get-the-session-data", - "name": "Get the session data", - "response": "\`\`\`json -{ - "data": { - "session": { - "access_token": "", - "token_type": "bearer", - "expires_in": 3600, - "expires_at": 1700000000, - "refresh_token": "", - "user": { - "id": "11111111-1111-1111-1111-111111111111", - "aud": "authenticated", - "role": "authenticated", - "email": "example@email.com", - "email_confirmed_at": "2024-01-01T00:00:00Z", - "phone": "", - "last_sign_in_at": "2024-01-01T00:00:00Z", - "app_metadata": { - "provider": "email", - "providers": [ - "email" - ] - }, - "user_metadata": { - "email": "example@email.com", - "email_verified": false, - "phone_verified": false, - "sub": "11111111-1111-1111-1111-111111111111" - }, - "identities": [ - { - "identity_id": "22222222-2222-2222-2222-222222222222", - "id": "11111111-1111-1111-1111-111111111111", - "user_id": "11111111-1111-1111-1111-111111111111", - "identity_data": { - "email": "example@email.com", - "email_verified": false, - "phone_verified": false, - "sub": "11111111-1111-1111-1111-111111111111" - }, - "provider": "email", - "last_sign_in_at": "2024-01-01T00:00:00Z", - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "email": "example@email.com" - } - ], - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "is_anonymous": false - } - } - }, - "error": null -} -\`\`\`", - }, - ], - "shortText": "Returns the session, refreshing it if necessary. - -The session returned can be null if the session is not detected which can happen in the event a user is not signed-in or has logged out. - -**IMPORTANT:** This method loads values directly from the storage attached -to the client. If that storage is based on request cookies for example, -the values in it may not be authentic and therefore it's strongly advised -against using this method and its results in such circumstances. A warning -will be emitted if this is detected. Use #getUser() instead.", - "text": "- Since the introduction of [asymmetric JWT signing keys](/docs/guides/auth/signing-keys), this method is considered low-level and we encourage you to use \`getClaims()\` or \`getUser()\` instead. -- Retrieves the current [user session](/docs/guides/auth/sessions) from the storage medium (local storage, cookies). -- The session contains an access token (signed JWT), a refresh token and the user object. -- If the session's access token is expired or is about to expire, this method will use the refresh token to refresh the session. -- When using in a browser, or you've called \`startAutoRefresh()\` in your environment (React Native, etc.) this function always returns a valid access token without refreshing the session itself, as this is done in the background. This function returns very fast. -- **IMPORTANT SECURITY NOTICE:** If using an insecure storage medium, such as cookies or request headers, the user object returned by this function **must not be trusted**. Always verify the JWT using \`getClaims()\` or your own JWT verification library to securely establish the user's identity and access. You can also use \`getUser()\` to fetch the user object directly from the Auth server for this purpose. -- Cross-tab refresh races are handled by the GoTrue server (the rotated token from the first tab is returned to subsequent tabs via the parent-of-active mechanism), so no client-side serialization is needed.", - }, - "name": "@supabase/auth-js.GoTrueClient.getSession", - "params": [], - "ret": { - "type": { - "awaited": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "session", - "type": { - "name": "Session", - "properties": [ - { - "comment": { - "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value.", - }, - "name": "access_token", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed.", - }, - "isOptional": true, - "name": "expires_at", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed.", - }, - "name": "expires_in", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API. -Not all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token.", - }, - "isOptional": true, - "name": "provider_refresh_token", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "string", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used.", - }, - "isOptional": true, - "name": "provider_token", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "string", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "A one-time used refresh token that never expires.", - }, - "name": "refresh_token", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "token_type", - "type": { - "type": "literal", - "value": "bearer", - }, - }, - { - "comment": { - "shortText": "When using a separate user storage, accessing properties of this object will throw an error.", - }, - "name": "user", - "type": { - "name": "User", - "properties": [ - { - "isOptional": true, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "banned_until", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmation_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "deleted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_change_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "factors", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "invited_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_sso_user", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "recovery_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "session", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "session", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueClient.getUser": { - "comment": { - "examples": [ - { - "code": "\`\`\`js -const { data: { user } } = await supabase.auth.getUser() -\`\`\`", - "data": undefined, - "description": undefined, - "id": "get-the-logged-in-user-with-the-current-existing-session", - "name": "Get the logged in user with the current existing session", - "response": "\`\`\`json -{ - "data": { - "user": { - "id": "11111111-1111-1111-1111-111111111111", - "aud": "authenticated", - "role": "authenticated", - "email": "example@email.com", - "email_confirmed_at": "2024-01-01T00:00:00Z", - "phone": "", - "confirmed_at": "2024-01-01T00:00:00Z", - "last_sign_in_at": "2024-01-01T00:00:00Z", - "app_metadata": { - "provider": "email", - "providers": [ - "email" - ] - }, - "user_metadata": { - "email": "example@email.com", - "email_verified": false, - "phone_verified": false, - "sub": "11111111-1111-1111-1111-111111111111" - }, - "identities": [ - { - "identity_id": "22222222-2222-2222-2222-222222222222", - "id": "11111111-1111-1111-1111-111111111111", - "user_id": "11111111-1111-1111-1111-111111111111", - "identity_data": { - "email": "example@email.com", - "email_verified": false, - "phone_verified": false, - "sub": "11111111-1111-1111-1111-111111111111" - }, - "provider": "email", - "last_sign_in_at": "2024-01-01T00:00:00Z", - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "email": "example@email.com" - } - ], - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "is_anonymous": false - } - }, - "error": null -} -\`\`\`", - }, - { - "code": "\`\`\`js -const { data: { user } } = await supabase.auth.getUser(jwt) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "get-the-logged-in-user-with-a-custom-access-token-jwt", - "name": "Get the logged in user with a custom access token jwt", - "response": undefined, - }, - ], - "shortText": "Gets the current user details if there is an existing session. This method -performs a network request to the Supabase Auth server, so the returned -value is authentic and can be used to base authorization rules on.", - "text": "- This method fetches the user object from the database instead of local session. -- This method is useful for checking if the user is authorized because it validates the user's access token JWT on the server. -- Should always be used when checking for user authorization on the server. On the client, you can instead use \`getSession().session.user\` for faster results. \`getSession\` is insecure on the server.", - }, - "name": "@supabase/auth-js.GoTrueClient.getUser", - "params": [ - { - "comment": { - "shortText": "Takes in an optional access token JWT. If no JWT is provided, the JWT from the current session is used.", - }, - "isOptional": true, - "name": "jwt", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "UserResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "user", - "type": { - "name": "User", - "properties": [ - { - "isOptional": true, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "banned_until", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmation_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "deleted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_change_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "factors", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "invited_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_sso_user", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "recovery_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "properties": [ - { - "name": "user", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueClient.getUserIdentities": { - "comment": { - "examples": [ - { - "code": "\`\`\`js -const { data, error } = await supabase.auth.getUserIdentities() -\`\`\`", - "data": undefined, - "description": undefined, - "id": "returns-a-list-of-identities-linked-to-the-user", - "name": "Returns a list of identities linked to the user", - "response": "\`\`\`json -{ - "data": { - "identities": [ - { - "identity_id": "22222222-2222-2222-2222-222222222222", - "id": "2024-01-01T00:00:00Z", - "user_id": "2024-01-01T00:00:00Z", - "identity_data": { - "email": "example@email.com", - "email_verified": false, - "phone_verified": false, - "sub": "11111111-1111-1111-1111-111111111111" - }, - "provider": "email", - "last_sign_in_at": "2024-01-01T00:00:00Z", - "created_at": "2024-01-01T00:00:00Z", - "updated_at": "2024-01-01T00:00:00Z", - "email": "example@email.com" - } - ] - }, - "error": null -} -\`\`\`", - }, - ], - "shortText": "Gets all the identities linked to a user.", - "text": "- The user needs to be signed in to call \`getUserIdentities()\`.", - }, - "name": "@supabase/auth-js.GoTrueClient.getUserIdentities", - "params": [], - "ret": { - "type": { - "awaited": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "error", - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueClient.initialize": { - "comment": { - "shortText": "Initializes the client session either from the url or from storage. -This method is automatically called when instantiating the client, but should also be called -manually when checking for an error from an auth redirect (oauth, magiclink, password recovery, etc).", - }, - "name": "@supabase/auth-js.GoTrueClient.initialize", - "params": [], - "ret": { - "type": { - "awaited": { - "name": "InitializeResult", - "properties": [ - { - "name": "error", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "AuthError", - "type": "nameOnly", - }, - { - "type": "literal", - "value": null, - }, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueClient.isThrowOnErrorEnabled": { - "comment": { - "shortText": "Returns whether error throwing mode is enabled for this client.", - }, - "name": "@supabase/auth-js.GoTrueClient.isThrowOnErrorEnabled", - "params": [], - "ret": { - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - }, - "@supabase/auth-js.GoTrueClient.linkIdentity": { - "altSignatures": [ - { - "params": [ - { - "name": "credentials", - "type": { - "name": "SignInWithIdTokenCredentials", - "properties": [ - { - "comment": { - "shortText": "If the ID token contains an \`at_hash\` claim, then the hash of this value is compared to the value in the ID token.", - }, - "isOptional": true, - "name": "access_token", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "If the ID token contains a \`nonce\` claim, then the hash of this value is compared to the value in the ID token.", - }, - "isOptional": true, - "name": "nonce", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "options", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "comment": { - "shortText": "Verification token received when the user completes the captcha on the site.", - }, - "isOptional": true, - "name": "captchaToken", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "comment": { - "shortText": "Provider name or OIDC \`iss\` value identifying which provider should be used to verify the provided token. Supported names: \`google\`, \`apple\`, \`azure\`, \`facebook\`, \`kakao\`. Use the \`custom:\` prefix for custom OIDC providers (e.g. \`custom:my-oidc-provider\`).", - }, - "name": "provider", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "google", - }, - { - "type": "literal", - "value": "apple", - }, - { - "type": "literal", - "value": "azure", - }, - { - "type": "literal", - "value": "facebook", - }, - { - "type": "literal", - "value": "kakao", - }, - undefined, - undefined, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "OIDC ID token issued by the specified provider. The \`iss\` claim in the ID token must match the supplied provider. Some ID tokens contain an \`at_hash\` which require that you provide an \`access_token\` value to be accepted properly. If the token contains a \`nonce\` claim you must supply the nonce used to obtain the ID token.", - }, - "name": "token", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "AuthTokenResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "session", - "type": { - "name": "Session", - "properties": [ - { - "comment": { - "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value.", - }, - "name": "access_token", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed.", - }, - "isOptional": true, - "name": "expires_at", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed.", - }, - "name": "expires_in", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API. -Not all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token.", - }, - "isOptional": true, - "name": "provider_refresh_token", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "string", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used.", - }, - "isOptional": true, - "name": "provider_token", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "string", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "A one-time used refresh token that never expires.", - }, - "name": "refresh_token", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "token_type", - "type": { - "type": "literal", - "value": "bearer", - }, - }, - { - "comment": { - "shortText": "When using a separate user storage, accessing properties of this object will throw an error.", - }, - "name": "user", - "type": { - "name": "User", - "properties": [ - { - "isOptional": true, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "banned_until", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmation_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "deleted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_change_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "factors", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "invited_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_sso_user", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "recovery_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "user", - "type": { - "name": "User", - "properties": [ - { - "isOptional": true, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "banned_until", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmation_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "deleted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_change_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "factors", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "invited_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_sso_user", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "recovery_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "properties": [ - { - "name": "session", - "type": { - "type": "literal", - "value": null, - }, - }, - { - "name": "user", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - ], - "comment": { - "examples": [ - { - "code": "\`\`\`js -const { data, error } = await supabase.auth.linkIdentity({ - provider: 'github' -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "link-an-identity-to-a-user", - "name": "Link an identity to a user", - "response": "\`\`\`json -{ - data: { - provider: 'github', - url: - }, - error: null -} -\`\`\`", - }, - ], - "shortText": "Links an oauth identity to an existing user. -This method supports the PKCE flow.", - "text": "- The **Enable Manual Linking** option must be enabled from your [project's authentication settings](/dashboard/project/_/auth/providers). -- The user needs to be signed in to call \`linkIdentity()\`. -- If the candidate identity is already linked to the existing user or another user, \`linkIdentity()\` will fail. -- If \`linkIdentity\` is run in the browser, the user is automatically redirected to the returned URL. On the server, you should handle the redirect.", - }, - "name": "@supabase/auth-js.GoTrueClient.linkIdentity", - "params": [ - { - "name": "credentials", - "type": { - "name": "SignInWithOAuthCredentials", - "properties": [ - { - "isOptional": true, - "name": "options", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "comment": { - "shortText": "An object of query params", - }, - "isOptional": true, - "name": "queryParams", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "string", - "type": "intrinsic", - }, - }, - }, - { - "comment": { - "shortText": "A URL to send the user to after they are confirmed.", - }, - "isOptional": true, - "name": "redirectTo", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A space-separated list of scopes granted to the OAuth application.", - }, - "isOptional": true, - "name": "scopes", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "If set to true does not immediately redirect the current browser context to visit the OAuth authorization page for the provider.", - }, - "isOptional": true, - "name": "skipBrowserRedirect", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "comment": { - "shortText": "One of the providers supported by GoTrue.", - }, - "name": "provider", - "type": { - "name": "Provider", - "subTypes": [ - { - "type": "literal", - "value": "apple", - }, - { - "type": "literal", - "value": "azure", - }, - { - "type": "literal", - "value": "bitbucket", - }, - { - "type": "literal", - "value": "discord", - }, - { - "type": "literal", - "value": "facebook", - }, - { - "type": "literal", - "value": "figma", - }, - { - "type": "literal", - "value": "github", - }, - { - "type": "literal", - "value": "gitlab", - }, - { - "type": "literal", - "value": "google", - }, - { - "type": "literal", - "value": "kakao", - }, - { - "type": "literal", - "value": "keycloak", - }, - { - "type": "literal", - "value": "linkedin", - }, - { - "type": "literal", - "value": "linkedin_oidc", - }, - { - "type": "literal", - "value": "notion", - }, - { - "type": "literal", - "value": "slack", - }, - { - "type": "literal", - "value": "slack_oidc", - }, - { - "type": "literal", - "value": "spotify", - }, - { - "type": "literal", - "value": "twitch", - }, - { - "type": "literal", - "value": "twitter", - }, - { - "type": "literal", - "value": "x", - }, - { - "type": "literal", - "value": "workos", - }, - { - "type": "literal", - "value": "zoom", - }, - { - "type": "literal", - "value": "fly", - }, - undefined, - ], - "type": "union", - }, - }, - ], - "type": "object", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "OAuthResponse", - "subTypes": [ - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "provider", - "type": { - "name": "Provider", - "subTypes": [ - { - "type": "literal", - "value": "apple", - }, - { - "type": "literal", - "value": "azure", - }, - { - "type": "literal", - "value": "bitbucket", - }, - { - "type": "literal", - "value": "discord", - }, - { - "type": "literal", - "value": "facebook", - }, - { - "type": "literal", - "value": "figma", - }, - { - "type": "literal", - "value": "github", - }, - { - "type": "literal", - "value": "gitlab", - }, - { - "type": "literal", - "value": "google", - }, - { - "type": "literal", - "value": "kakao", - }, - { - "type": "literal", - "value": "keycloak", - }, - { - "type": "literal", - "value": "linkedin", - }, - { - "type": "literal", - "value": "linkedin_oidc", - }, - { - "type": "literal", - "value": "notion", - }, - { - "type": "literal", - "value": "slack", - }, - { - "type": "literal", - "value": "slack_oidc", - }, - { - "type": "literal", - "value": "spotify", - }, - { - "type": "literal", - "value": "twitch", - }, - { - "type": "literal", - "value": "twitter", - }, - { - "type": "literal", - "value": "x", - }, - { - "type": "literal", - "value": "workos", - }, - { - "type": "literal", - "value": "zoom", - }, - { - "type": "literal", - "value": "fly", - }, - undefined, - ], - "type": "union", - }, - }, - { - "name": "url", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "provider", - "type": { - "name": "Provider", - "subTypes": [ - { - "type": "literal", - "value": "apple", - }, - { - "type": "literal", - "value": "azure", - }, - { - "type": "literal", - "value": "bitbucket", - }, - { - "type": "literal", - "value": "discord", - }, - { - "type": "literal", - "value": "facebook", - }, - { - "type": "literal", - "value": "figma", - }, - { - "type": "literal", - "value": "github", - }, - { - "type": "literal", - "value": "gitlab", - }, - { - "type": "literal", - "value": "google", - }, - { - "type": "literal", - "value": "kakao", - }, - { - "type": "literal", - "value": "keycloak", - }, - { - "type": "literal", - "value": "linkedin", - }, - { - "type": "literal", - "value": "linkedin_oidc", - }, - { - "type": "literal", - "value": "notion", - }, - { - "type": "literal", - "value": "slack", - }, - { - "type": "literal", - "value": "slack_oidc", - }, - { - "type": "literal", - "value": "spotify", - }, - { - "type": "literal", - "value": "twitch", - }, - { - "type": "literal", - "value": "twitter", - }, - { - "type": "literal", - "value": "x", - }, - { - "type": "literal", - "value": "workos", - }, - { - "type": "literal", - "value": "zoom", - }, - { - "type": "literal", - "value": "fly", - }, - undefined, - ], - "type": "union", - }, - }, - { - "name": "url", - "type": { - "type": "literal", - "value": null, - }, - }, - ], - "type": "object", - }, - }, - { - "name": "error", - "type": { - "name": "AuthError", - "type": "nameOnly", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": "Promise", - "type": "promise", - }, - }, - }, - "@supabase/auth-js.GoTrueClient.onAuthStateChange": { - "altSignatures": [ - { - "params": [ - { - "comment": { - "shortText": "A callback function to be invoked when an auth event happens.", - }, - "name": "callback", - "type": { - "comment": undefined, - "name": Symbol(anonymous), - "params": [ - { - "name": "event", - "type": { - "name": "AuthChangeEvent", - "subTypes": [ - { - "type": "literal", - "value": "INITIAL_SESSION", - }, - { - "type": "literal", - "value": "PASSWORD_RECOVERY", - }, - { - "type": "literal", - "value": "SIGNED_IN", - }, - { - "type": "literal", - "value": "SIGNED_OUT", - }, - { - "type": "literal", - "value": "TOKEN_REFRESHED", - }, - { - "type": "literal", - "value": "USER_UPDATED", - }, - { - "name": "AuthChangeEventMFA", - "type": "literal", - "value": "MFA_CHALLENGE_VERIFIED", - }, - ], - "type": "union", - }, - }, - { - "name": "session", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "Session", - "properties": [ - { - "comment": { - "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value.", - }, - "name": "access_token", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed.", - }, - "isOptional": true, - "name": "expires_at", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed.", - }, - "name": "expires_in", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API. -Not all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token.", - }, - "isOptional": true, - "name": "provider_refresh_token", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "string", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used.", - }, - "isOptional": true, - "name": "provider_token", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "string", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "A one-time used refresh token that never expires.", - }, - "name": "refresh_token", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "token_type", - "type": { - "type": "literal", - "value": "bearer", - }, - }, - { - "comment": { - "shortText": "When using a separate user storage, accessing properties of this object will throw an error.", - }, - "name": "user", - "type": { - "name": "User", - "properties": [ - { - "isOptional": true, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "banned_until", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmation_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "deleted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_change_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "factors", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "invited_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_sso_user", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "recovery_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - }, - ], - "ret": { - "type": { - "awaited": { - "name": "void", - "type": "intrinsic", - }, - "name": "Promise", - "type": "promise", - }, - }, - "type": "function", - }, - }, - ], - "ret": { - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "data", - "type": { - "name": Symbol(anonymous), - "properties": [ - { - "name": "subscription", - "type": { - "name": "Subscription", - "properties": [ - { - "comment": { - "shortText": "The function to call every time there is an event. eg: (eventName) => {}", - }, - "name": "callback", - "type": { - "comment": undefined, - "name": Symbol(anonymous), - "params": [ - { - "name": "event", - "type": { - "name": "AuthChangeEvent", - "subTypes": [ - { - "type": "literal", - "value": "INITIAL_SESSION", - }, - { - "type": "literal", - "value": "PASSWORD_RECOVERY", - }, - { - "type": "literal", - "value": "SIGNED_IN", - }, - { - "type": "literal", - "value": "SIGNED_OUT", - }, - { - "type": "literal", - "value": "TOKEN_REFRESHED", - }, - { - "type": "literal", - "value": "USER_UPDATED", - }, - { - "name": "AuthChangeEventMFA", - "type": "literal", - "value": "MFA_CHALLENGE_VERIFIED", - }, - ], - "type": "union", - }, - }, - { - "name": "session", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "Session", - "properties": [ - { - "comment": { - "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value.", - }, - "name": "access_token", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed.", - }, - "isOptional": true, - "name": "expires_at", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed.", - }, - "name": "expires_in", - "type": { - "name": "number", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API. -Not all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token.", - }, - "isOptional": true, - "name": "provider_refresh_token", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "string", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used.", - }, - "isOptional": true, - "name": "provider_token", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": null, - }, - { - "name": "string", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "A one-time used refresh token that never expires.", - }, - "name": "refresh_token", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "token_type", - "type": { - "type": "literal", - "value": "bearer", - }, - }, - { - "comment": { - "shortText": "When using a separate user storage, accessing properties of this object will throw an error.", - }, - "name": "user", - "type": { - "name": "User", - "properties": [ - { - "isOptional": true, - "name": "action_link", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "app_metadata", - "type": { - "name": "UserAppMetadata", - "properties": [ - { - "comment": { - "shortText": "The first provider that the user used to sign up with.", - }, - "isOptional": true, - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "A list of all providers that the user has linked to their account.", - }, - "isOptional": true, - "name": "providers", - "type": { - "elemType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - ], - "type": "object", - }, - }, - { - "name": "aud", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "banned_until", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmation_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "deleted_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_change_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "email_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "factors", - "type": { - "elemType": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - { - "name": "Factor", - "properties": [ - { - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "Type of factor. \`totp\` and \`phone\` supported with this version", - }, - "name": "factor_type", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors.", - }, - "isOptional": true, - "name": "friendly_name", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "ID of the factor.", - }, - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_challenged_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "comment": { - "shortText": "The verification status of the factor, default is \`unverified\` after \`.enroll()\`, then \`verified\` after the user verifies it with \`.verify()\`", - }, - "name": "status", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "type": "literal", - "value": "totp", - }, - { - "type": "literal", - "value": "phone", - }, - { - "type": "literal", - "value": "webauthn", - }, - ], - "type": "union", - }, - }, - { - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identities", - "type": { - "elemType": { - "name": "UserIdentity", - "properties": [ - { - "isOptional": true, - "name": "created_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "identity_data", - "type": { - "keyType": { - "name": "string", - "type": "intrinsic", - }, - "name": Symbol(anonymous), - "type": "index signature", - "valueType": { - "name": "any", - "type": "intrinsic", - }, - }, - }, - { - "name": "identity_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "provider", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_id", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - ], - "type": "object", - }, - "name": Symbol(anonymous), - "type": "array", - }, - }, - { - "isOptional": true, - "name": "invited_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_anonymous", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "is_sso_user", - "type": { - "name": "boolean", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "last_sign_in_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_email", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "new_phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "phone_confirmed_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "recovery_sent_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "role", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "isOptional": true, - "name": "updated_at", - "type": { - "name": "string", - "type": "intrinsic", - }, - }, - { - "name": "user_metadata", - "type": { - "name": "UserMetadata", - "properties": [], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - ], - "type": "union", - }, - }, - ], - "ret": { - "type": { - "name": "void", - "type": "intrinsic", - }, - }, - "type": "function", - }, - }, - { - "comment": { - "shortText": "A unique identifier for this subscription, set by the client. -This is an internal identifier used for managing callbacks and should not be -relied upon by application code. Use the unsubscribe() method to remove listeners.", - }, - "name": "id", - "type": { - "name": Symbol(anonymous), - "subTypes": [ - { - "name": "string", - "type": "intrinsic", - }, - { - "name": "symbol", - "type": "intrinsic", - }, - ], - "type": "union", - }, - }, - { - "comment": { - "shortText": "Call this to remove the listener.", - }, - "name": "unsubscribe", - "type": { - "comment": undefined, - "name": Symbol(anonymous), - "params": [], - "ret": { - "type": { - "name": "void", - "type": "intrinsic", - }, - }, - "type": "function", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - ], - "type": "object", - }, - }, - }, - ], - "comment": { - "examples": [ - { - "code": "\`\`\`js -const { data } = supabase.auth.onAuthStateChange((event, session) => { - console.log(event, session) - - if (event === 'INITIAL_SESSION') { - // handle initial session - } else if (event === 'SIGNED_IN') { - // handle sign in event - } else if (event === 'SIGNED_OUT') { - // handle sign out event - } else if (event === 'PASSWORD_RECOVERY') { - // handle password recovery event - } else if (event === 'TOKEN_REFRESHED') { - // handle token refreshed event - } else if (event === 'USER_UPDATED') { - // handle user updated event - } -}) - -// call unsubscribe to remove the callback -data.subscription.unsubscribe() -\`\`\`", - "data": undefined, - "description": undefined, - "id": "listen-to-auth-changes", - "name": "Listen to auth changes", - "response": undefined, - }, - { - "code": "\`\`\`js -supabase.auth.onAuthStateChange((event, session) => { - if (event === 'SIGNED_OUT') { - console.log('SIGNED_OUT', session) - - // clear local and session storage - [ - window.localStorage, - window.sessionStorage, - ].forEach((storage) => { - Object.entries(storage) - .forEach(([key]) => { - storage.removeItem(key) - }) - }) - } -}) -\`\`\`", - "data": undefined, - "description": "Make sure you clear out any local data, such as local and session storage, after the client library has detected the user's sign out.", - "id": "listen-to-sign-out", - "name": "Listen to sign out", - "response": undefined, - }, - { - "code": "\`\`\`js -// Register this immediately after calling createClient! -// Because signInWithOAuth causes a redirect, you need to fetch the -// provider tokens from the callback. -supabase.auth.onAuthStateChange((event, session) => { - if (session && session.provider_token) { - window.localStorage.setItem('oauth_provider_token', session.provider_token) - } - - if (session && session.provider_refresh_token) { - window.localStorage.setItem('oauth_provider_refresh_token', session.provider_refresh_token) - } - - if (event === 'SIGNED_OUT') { - window.localStorage.removeItem('oauth_provider_token') - window.localStorage.removeItem('oauth_provider_refresh_token') - } -}) -\`\`\`", - "data": undefined, - "description": "When using [OAuth (Social Login)](/docs/guides/auth/social-login) you sometimes wish to get access to the provider's access token and refresh token, in order to call provider APIs in the name of the user. - -For example, if you are using [Sign in with Google](/docs/guides/auth/social-login/auth-google) you may want to use the provider token to call Google APIs on behalf of the user. Supabase Auth does not keep track of the provider access and refresh token, but does return them for you once, immediately after sign in. You can use the \`onAuthStateChange\` method to listen for the presence of the provider tokens and store them in local storage. You can further send them to your server's APIs for use on the backend. - -Finally, make sure you remove them from local storage on the \`SIGNED_OUT\` event. If the OAuth provider supports token revocation, make sure you call those APIs either from the frontend or schedule them to be called on the backend.", - "id": "store-oauth-provider-tokens-on-sign-in", - "name": "Store OAuth provider tokens on sign in", - "response": undefined, - }, - { - "code": "\`\`\`js -const SessionContext = React.createContext(null) - -function main() { - const [session, setSession] = React.useState(null) - - React.useEffect(() => { - const {data: { subscription }} = supabase.auth.onAuthStateChange( - (event, session) => { - if (event === 'SIGNED_OUT') { - setSession(null) - } else if (session) { - setSession(session) - } - }) - - return () => { - subscription.unsubscribe() - } - }, []) - - return ( - - - - ) -} -\`\`\`", - "data": undefined, - "description": "Instead of relying on \`supabase.auth.getSession()\` within your React components, you can use a [React Context](https://react.dev/reference/react/createContext) to store the latest session information from the \`onAuthStateChange\` callback and access it that way.", - "id": "use-react-context-for-the-user-s-session", - "name": "Use React Context for the User's session", - "response": undefined, - }, - { - "code": "\`\`\`js -supabase.auth.onAuthStateChange((event, session) => { - if (event === 'PASSWORD_RECOVERY') { - console.log('PASSWORD_RECOVERY', session) - // show screen to update user's password - showPasswordResetScreen(true) - } -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "listen-to-password-recovery-events", - "name": "Listen to password recovery events", - "response": undefined, - }, - { - "code": "\`\`\`js -supabase.auth.onAuthStateChange((event, session) => { - if (event === 'SIGNED_IN') console.log('SIGNED_IN', session) -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "listen-to-sign-in", - "name": "Listen to sign in", - "response": undefined, - }, - { - "code": "\`\`\`js -supabase.auth.onAuthStateChange((event, session) => { - if (event === 'TOKEN_REFRESHED') console.log('TOKEN_REFRESHED', session) -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "listen-to-token-refresh", - "name": "Listen to token refresh", - "response": undefined, - }, - { - "code": "\`\`\`js -supabase.auth.onAuthStateChange((event, session) => { - if (event === 'USER_UPDATED') console.log('USER_UPDATED', session) -}) -\`\`\`", - "data": undefined, - "description": undefined, - "id": "listen-to-user-updates", - "name": "Listen to user updates", - "response": undefined, - }, - ], - "shortText": "Receive a notification every time an auth event happens. -Safe to use without an async function as callback.", - "text": "- Subscribes to important events occurring on the user's session. -- Use on the frontend/client. It is less useful on the server. -- Events are emitted across tabs to keep your application's UI up-to-date. Some events can fire very frequently, based on the number of tabs open. Use a quick and efficient callback function, and defer or debounce as many operations as you can to be performed outside of the callback. -- Callbacks can be \`async\` and can safely call other Supabase auth methods (\`getUser\`, \`setSession\`, etc.) from inside the callback. -- Keep callbacks quick. Events are awaited in order, so a slow callback delays subsequent events to subscribers in this tab. -- Emitted events: - - \`INITIAL_SESSION\` - - Emitted right after the Supabase client is constructed and the initial session from storage is loaded. - - \`SIGNED_IN\` - - Emitted each time a user session is confirmed or re-established, including on user sign in and when refocusing a tab. - - Avoid making assumptions as to when this event is fired, this may occur even when the user is already signed in. Instead, check the user object attached to the event to see if a new user has signed in and update your application's UI. - - This event can fire very frequently depending on the number of tabs open in your application. - - \`SIGNED_OUT\` - - Emitted when the user signs out. This can be after: - - A call to \`supabase.auth.signOut()\`. - - After the user's session has expired for any reason: - - User has signed out on another device. - - The session has reached its timebox limit or inactivity timeout. - - User has signed in on another device with single session per user enabled. - - Check the [User Sessions](/docs/guides/auth/sessions) docs for more information. - - Use this to clean up any local storage your application has associated with the user. - - \`TOKEN_REFRESHED\` - - Emitted each time a new access and refresh token are fetched for the signed in user. - - It's best practice and highly recommended to extract the access token (JWT) and store it in memory for further use in your application. - - Avoid frequent calls to \`supabase.auth.getSession()\` for the same purpose. - - There is a background process that keeps track of when the session should be refreshed so you will always receive valid tokens by listening to this event. - - The frequency of this event is related to the JWT expiry limit configured on your project. - - \`USER_UPDATED\` - - Emitted each time the \`supabase.auth.updateUser()\` method finishes successfully. Listen to it to update your application's UI based on new profile information. - - \`PASSWORD_RECOVERY\` - - Emitted instead of the \`SIGNED_IN\` event when the user lands on a page that includes a password recovery link in the URL. - - Use it to show a UI to the user where they can [reset their password](/docs/guides/auth/passwords#resetting-a-users-password-forgot-password).", - }, - "name": "@supabase/auth-js.GoTrueClient.onAuthStateChange", - "params": [Array], - "ret": [Object], - }, - "@supabase/auth-js.GoTrueClient.reauthenticate": [Object], - "@supabase/auth-js.GoTrueClient.refreshSession": [Object], - "@supabase/auth-js.GoTrueClient.registerPasskey": [Object], - "@supabase/auth-js.GoTrueClient.resend": [Object], - "@supabase/auth-js.GoTrueClient.resetPasswordForEmail": [Object], - "@supabase/auth-js.GoTrueClient.setSession": [Object], - "@supabase/auth-js.GoTrueClient.signInAnonymously": [Object], - "@supabase/auth-js.GoTrueClient.signInWithIdToken": [Object], - "@supabase/auth-js.GoTrueClient.signInWithOAuth": [Object], - "@supabase/auth-js.GoTrueClient.signInWithOtp": [Object], - "@supabase/auth-js.GoTrueClient.signInWithPasskey": [Object], - "@supabase/auth-js.GoTrueClient.signInWithPassword": [Object], - "@supabase/auth-js.GoTrueClient.signInWithSSO": [Object], - "@supabase/auth-js.GoTrueClient.signInWithWeb3": [Object], - "@supabase/auth-js.GoTrueClient.signOut": [Object], - "@supabase/auth-js.GoTrueClient.signUp": [Object], - "@supabase/auth-js.GoTrueClient.startAutoRefresh": [Object], - "@supabase/auth-js.GoTrueClient.stopAutoRefresh": [Object], - "@supabase/auth-js.GoTrueClient.unlinkIdentity": [Object], - "@supabase/auth-js.GoTrueClient.updateUser": [Object], - "@supabase/auth-js.GoTrueClient.verifyOtp": [Object], - "@supabase/auth-js.GoTrueMFAApi.challenge": [Object], - "@supabase/auth-js.GoTrueMFAApi.challengeAndVerify": [Object], - "@supabase/auth-js.GoTrueMFAApi.enroll": [Object], - "@supabase/auth-js.GoTrueMFAApi.getAuthenticatorAssuranceLevel": [Object], - "@supabase/auth-js.GoTrueMFAApi.listFactors": [Object], - "@supabase/auth-js.GoTrueMFAApi.unenroll": [Object], - "@supabase/auth-js.GoTrueMFAApi.verify": [Object], - "@supabase/auth-js.NavigatorLockAcquireTimeoutError.constructor": [Object], - "@supabase/auth-js.isAuthApiError": [Object], - "@supabase/auth-js.isAuthError": [Object], - "@supabase/auth-js.isAuthImplicitGrantRedirectError": [Object], - "@supabase/auth-js.isAuthPKCECodeVerifierMissingError": [Object], - "@supabase/auth-js.isAuthRefreshDiscardedError": [Object], - "@supabase/auth-js.isAuthRetryableFetchError": [Object], - "@supabase/auth-js.isAuthSessionMissingError": [Object], - "@supabase/auth-js.isAuthWeakPasswordError": [Object], - "@supabase/auth-js.navigatorLock": [Object], - "@supabase/auth-js.processLock": [Object], - "@supabase/functions-js.FunctionsClient.constructor": [Object], - "@supabase/functions-js.FunctionsClient.invoke": [Object], - "@supabase/functions-js.FunctionsClient.setAuth": [Object], - "@supabase/functions-js.FunctionsError.constructor": [Object], - "@supabase/functions-js.FunctionsError.toJSON": [Object], - "@supabase/functions-js.FunctionsFetchError.constructor": [Object], - "@supabase/functions-js.FunctionsFetchError.toJSON": [Object], - "@supabase/functions-js.FunctionsHttpError.constructor": [Object], - "@supabase/functions-js.FunctionsHttpError.toJSON": [Object], - "@supabase/functions-js.FunctionsRelayError.constructor": [Object], - "@supabase/functions-js.FunctionsRelayError.toJSON": [Object], - "@supabase/postgrest-js.PostgrestBuilder.constructor": [Object], - "@supabase/postgrest-js.PostgrestBuilder.overrideTypes": [Object], - "@supabase/postgrest-js.PostgrestBuilder.retry": [Object], - "@supabase/postgrest-js.PostgrestBuilder.returns": [Object], - "@supabase/postgrest-js.PostgrestBuilder.setHeader": [Object], - "@supabase/postgrest-js.PostgrestBuilder.stripNulls": [Object], - "@supabase/postgrest-js.PostgrestBuilder.then": [Object], - "@supabase/postgrest-js.PostgrestBuilder.throwOnError": [Object], - "@supabase/postgrest-js.PostgrestClient.constructor": [Object], - "@supabase/postgrest-js.PostgrestClient.from": [Object], - "@supabase/postgrest-js.PostgrestClient.rpc": [Object], - "@supabase/postgrest-js.PostgrestClient.schema": [Object], - "@supabase/postgrest-js.PostgrestError.constructor": [Object], - "@supabase/postgrest-js.PostgrestError.toJSON": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.abortSignal": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.constructor": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.containedBy": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.contains": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.csv": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.eq": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.explain": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.filter": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.geojson": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.gt": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.gte": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.ilike": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.ilikeAllOf": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.ilikeAnyOf": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.in": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.is": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.isDistinct": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.like": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.likeAllOf": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.likeAnyOf": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.limit": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.lt": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.lte": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.match": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.maxAffected": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.maybeSingle": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.neq": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.not": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.notIn": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.or": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.order": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.overlaps": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.overrideTypes": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.range": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.rangeAdjacent": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.rangeGt": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.rangeGte": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.rangeLt": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.rangeLte": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.regexIMatch": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.regexMatch": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.retry": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.returns": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.rollback": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.select": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.setHeader": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.single": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.stripNulls": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.textSearch": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.then": [Object], - "@supabase/postgrest-js.PostgrestFilterBuilder.throwOnError": [Object], - "@supabase/postgrest-js.PostgrestQueryBuilder.constructor": [Object], - "@supabase/postgrest-js.PostgrestQueryBuilder.delete": [Object], - "@supabase/postgrest-js.PostgrestQueryBuilder.insert": [Object], - "@supabase/postgrest-js.PostgrestQueryBuilder.select": [Object], - "@supabase/postgrest-js.PostgrestQueryBuilder.update": [Object], - "@supabase/postgrest-js.PostgrestQueryBuilder.upsert": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.abortSignal": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.constructor": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.csv": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.explain": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.geojson": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.limit": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.maxAffected": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.maybeSingle": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.order": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.overrideTypes": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.range": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.retry": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.returns": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.rollback": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.select": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.setHeader": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.single": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.stripNulls": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.then": [Object], - "@supabase/postgrest-js.PostgrestTransformBuilder.throwOnError": [Object], - "@supabase/realtime-js.RealtimeChannel.constructor": [Object], - "@supabase/realtime-js.RealtimeChannel.copyBindings": [Object], - "@supabase/realtime-js.RealtimeChannel.httpSend": [Object], - "@supabase/realtime-js.RealtimeChannel.on": [Object], - "@supabase/realtime-js.RealtimeChannel.presenceState": [Object], - "@supabase/realtime-js.RealtimeChannel.send": [Object], - "@supabase/realtime-js.RealtimeChannel.subscribe": [Object], - "@supabase/realtime-js.RealtimeChannel.teardown": [Object], - "@supabase/realtime-js.RealtimeChannel.track": [Object], - "@supabase/realtime-js.RealtimeChannel.unsubscribe": [Object], - "@supabase/realtime-js.RealtimeChannel.untrack": [Object], - "@supabase/realtime-js.RealtimeChannel.updateJoinPayload": [Object], - "@supabase/realtime-js.RealtimeClient.channel": [Object], - "@supabase/realtime-js.RealtimeClient.connect": [Object], - "@supabase/realtime-js.RealtimeClient.connectionState": [Object], - "@supabase/realtime-js.RealtimeClient.constructor": [Object], - "@supabase/realtime-js.RealtimeClient.disconnect": [Object], - "@supabase/realtime-js.RealtimeClient.endpointURL": [Object], - "@supabase/realtime-js.RealtimeClient.getChannels": [Object], - "@supabase/realtime-js.RealtimeClient.isConnected": [Object], - "@supabase/realtime-js.RealtimeClient.isConnecting": [Object], - "@supabase/realtime-js.RealtimeClient.isDisconnecting": [Object], - "@supabase/realtime-js.RealtimeClient.log": [Object], - "@supabase/realtime-js.RealtimeClient.onHeartbeat": [Object], - "@supabase/realtime-js.RealtimeClient.push": [Object], - "@supabase/realtime-js.RealtimeClient.removeAllChannels": [Object], - "@supabase/realtime-js.RealtimeClient.removeChannel": [Object], - "@supabase/realtime-js.RealtimeClient.sendHeartbeat": [Object], - "@supabase/realtime-js.RealtimeClient.setAuth": [Object], - "@supabase/realtime-js.RealtimePresence.constructor": [Object], - "@supabase/realtime-js.WebSocketFactory.getWebSocketConstructor": [Object], - "@supabase/realtime-js.WebSocketFactory.isWebSocketSupported": [Object], - "@supabase/realtime-js.WebSocketLike.addEventListener": [Object], - "@supabase/realtime-js.WebSocketLike.close": [Object], - "@supabase/realtime-js.WebSocketLike.removeEventListener": [Object], - "@supabase/realtime-js.WebSocketLike.send": [Object], - "@supabase/realtime-js.WebSocketLikeConstructor.constructor": [Object], - "@supabase/storage-js.StorageApiError.constructor": [Object], - "@supabase/storage-js.StorageApiError.toJSON": [Object], - "@supabase/storage-js.StorageClient.constructor": [Object], - "@supabase/storage-js.StorageClient.createBucket": [Object], - "@supabase/storage-js.StorageClient.deleteBucket": [Object], - "@supabase/storage-js.StorageClient.emptyBucket": [Object], - "@supabase/storage-js.StorageClient.from": [Object], - "@supabase/storage-js.StorageClient.getBucket": [Object], - "@supabase/storage-js.StorageClient.listBuckets": [Object], - "@supabase/storage-js.StorageClient.setHeader": [Object], - "@supabase/storage-js.StorageClient.throwOnError": [Object], - "@supabase/storage-js.StorageClient.updateBucket": [Object], - "@supabase/storage-js.StorageError.constructor": [Object], - "@supabase/storage-js.StorageError.toJSON": [Object], - "@supabase/storage-js.StorageUnknownError.constructor": [Object], - "@supabase/storage-js.StorageUnknownError.toJSON": [Object], - "@supabase/storage-js.StorageVectorsApiError.constructor": [Object], - "@supabase/storage-js.StorageVectorsApiError.toJSON": [Object], - "@supabase/storage-js.StorageVectorsError.constructor": [Object], - "@supabase/storage-js.StorageVectorsError.toJSON": [Object], - "@supabase/storage-js.StorageVectorsUnknownError.constructor": [Object], - "@supabase/storage-js.StorageVectorsUnknownError.toJSON": [Object], - "@supabase/storage-js.isStorageError": [Object], - "@supabase/storage-js.isStorageVectorsError": [Object], - "@supabase/storage-js.packages/BlobDownloadBuilder.default.asStream": [Object], - "@supabase/storage-js.packages/BlobDownloadBuilder.default.catch": [Object], - "@supabase/storage-js.packages/BlobDownloadBuilder.default.constructor": [Object], - "@supabase/storage-js.packages/BlobDownloadBuilder.default.finally": [Object], - "@supabase/storage-js.packages/BlobDownloadBuilder.default.then": [Object], - "@supabase/storage-js.packages/StorageAnalyticsClient.default.constructor": [Object], - "@supabase/storage-js.packages/StorageAnalyticsClient.default.createBucket": [Object], - "@supabase/storage-js.packages/StorageAnalyticsClient.default.deleteBucket": [Object], - "@supabase/storage-js.packages/StorageAnalyticsClient.default.from": [Object], - "@supabase/storage-js.packages/StorageAnalyticsClient.default.listBuckets": [Object], - "@supabase/storage-js.packages/StorageAnalyticsClient.default.setHeader": [Object], - "@supabase/storage-js.packages/StorageAnalyticsClient.default.throwOnError": [Object], - "@supabase/storage-js.packages/StorageBucketApi.default.constructor": [Object], - "@supabase/storage-js.packages/StorageBucketApi.default.createBucket": [Object], - "@supabase/storage-js.packages/StorageBucketApi.default.deleteBucket": [Object], - "@supabase/storage-js.packages/StorageBucketApi.default.emptyBucket": [Object], - "@supabase/storage-js.packages/StorageBucketApi.default.getBucket": [Object], - "@supabase/storage-js.packages/StorageBucketApi.default.listBuckets": [Object], - "@supabase/storage-js.packages/StorageBucketApi.default.setHeader": [Object], - "@supabase/storage-js.packages/StorageBucketApi.default.throwOnError": [Object], - "@supabase/storage-js.packages/StorageBucketApi.default.updateBucket": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.constructor": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.copy": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.createSignedUploadUrl": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.createSignedUrl": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.createSignedUrls": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.download": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.exists": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.getPublicUrl": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.info": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.list": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.listV2": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.move": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.remove": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.setHeader": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.throwOnError": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.toBase64": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.update": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.upload": [Object], - "@supabase/storage-js.packages/StorageFileApi.default.uploadToSignedUrl": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.constructor": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.createBucket": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.deleteBucket": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.from": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.getBucket": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.listBuckets": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.setHeader": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.throwOnError": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.constructor": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.createIndex": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.deleteIndex": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.getIndex": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.listIndexes": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.setHeader": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.throwOnError": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.constructor": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.deleteVectors": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.getVectors": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.listVectors": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.putVectors": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.queryVectors": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.setHeader": [Object], - "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.throwOnError": [Object], - "@supabase/storage-js.packages/StreamDownloadBuilder.default.catch": [Object], - "@supabase/storage-js.packages/StreamDownloadBuilder.default.constructor": [Object], - "@supabase/storage-js.packages/StreamDownloadBuilder.default.finally": [Object], - "@supabase/storage-js.packages/StreamDownloadBuilder.default.then": [Object], - "@supabase/supabase-js.AuthApiError.constructor": [Object], - "@supabase/supabase-js.AuthApiError.toJSON": [Object], - "@supabase/supabase-js.AuthError.constructor": [Object], - "@supabase/supabase-js.AuthError.toJSON": [Object], - "@supabase/supabase-js.AuthImplicitGrantRedirectError.constructor": [Object], - "@supabase/supabase-js.AuthImplicitGrantRedirectError.toJSON": [Object], - "@supabase/supabase-js.AuthInvalidCredentialsError.constructor": [Object], - "@supabase/supabase-js.AuthInvalidCredentialsError.toJSON": [Object], - "@supabase/supabase-js.AuthInvalidJwtError.constructor": [Object], - "@supabase/supabase-js.AuthInvalidJwtError.toJSON": [Object], - "@supabase/supabase-js.AuthInvalidTokenResponseError.constructor": [Object], - "@supabase/supabase-js.AuthInvalidTokenResponseError.toJSON": [Object], - "@supabase/supabase-js.AuthOAuthServerApi.approveAuthorization": [Object], - "@supabase/supabase-js.AuthOAuthServerApi.denyAuthorization": [Object], - "@supabase/supabase-js.AuthOAuthServerApi.getAuthorizationDetails": [Object], - "@supabase/supabase-js.AuthOAuthServerApi.listGrants": [Object], - "@supabase/supabase-js.AuthOAuthServerApi.revokeGrant": [Object], - "@supabase/supabase-js.AuthPKCECodeVerifierMissingError.constructor": [Object], - "@supabase/supabase-js.AuthPKCECodeVerifierMissingError.toJSON": [Object], - "@supabase/supabase-js.AuthPKCEGrantCodeExchangeError.constructor": [Object], - "@supabase/supabase-js.AuthPKCEGrantCodeExchangeError.toJSON": [Object], - "@supabase/supabase-js.AuthPasskeyApi.delete": [Object], - "@supabase/supabase-js.AuthPasskeyApi.list": [Object], - "@supabase/supabase-js.AuthPasskeyApi.startAuthentication": [Object], - "@supabase/supabase-js.AuthPasskeyApi.startRegistration": [Object], - "@supabase/supabase-js.AuthPasskeyApi.update": [Object], - "@supabase/supabase-js.AuthPasskeyApi.verifyAuthentication": [Object], - "@supabase/supabase-js.AuthPasskeyApi.verifyRegistration": [Object], - "@supabase/supabase-js.AuthRefreshDiscardedError.constructor": [Object], - "@supabase/supabase-js.AuthRefreshDiscardedError.toJSON": [Object], - "@supabase/supabase-js.AuthRetryableFetchError.constructor": [Object], - "@supabase/supabase-js.AuthRetryableFetchError.toJSON": [Object], - "@supabase/supabase-js.AuthSessionMissingError.constructor": [Object], - "@supabase/supabase-js.AuthSessionMissingError.toJSON": [Object], - "@supabase/supabase-js.AuthUnknownError.constructor": [Object], - "@supabase/supabase-js.AuthUnknownError.toJSON": [Object], - "@supabase/supabase-js.AuthWeakPasswordError.constructor": [Object], - "@supabase/supabase-js.AuthWeakPasswordError.toJSON": [Object], - "@supabase/supabase-js.CustomAuthError.constructor": [Object], - "@supabase/supabase-js.CustomAuthError.toJSON": [Object], - "@supabase/supabase-js.FunctionsError.constructor": [Object], - "@supabase/supabase-js.FunctionsError.toJSON": [Object], - "@supabase/supabase-js.FunctionsFetchError.constructor": [Object], - "@supabase/supabase-js.FunctionsFetchError.toJSON": [Object], - "@supabase/supabase-js.FunctionsHttpError.constructor": [Object], - "@supabase/supabase-js.FunctionsHttpError.toJSON": [Object], - "@supabase/supabase-js.FunctionsRelayError.constructor": [Object], - "@supabase/supabase-js.FunctionsRelayError.toJSON": [Object], - "@supabase/supabase-js.GoTrueAdminApi.constructor": [Object], - "@supabase/supabase-js.GoTrueAdminApi.createUser": [Object], - "@supabase/supabase-js.GoTrueAdminApi.deleteUser": [Object], - "@supabase/supabase-js.GoTrueAdminApi.generateLink": [Object], - "@supabase/supabase-js.GoTrueAdminApi.getUserById": [Object], - "@supabase/supabase-js.GoTrueAdminApi.inviteUserByEmail": [Object], - "@supabase/supabase-js.GoTrueAdminApi.listUsers": [Object], - "@supabase/supabase-js.GoTrueAdminApi.signOut": [Object], - "@supabase/supabase-js.GoTrueAdminApi.updateUserById": [Object], - "@supabase/supabase-js.GoTrueAdminCustomProvidersApi.createProvider": [Object], - "@supabase/supabase-js.GoTrueAdminCustomProvidersApi.deleteProvider": [Object], - "@supabase/supabase-js.GoTrueAdminCustomProvidersApi.getProvider": [Object], - "@supabase/supabase-js.GoTrueAdminCustomProvidersApi.listProviders": [Object], - "@supabase/supabase-js.GoTrueAdminCustomProvidersApi.updateProvider": [Object], - "@supabase/supabase-js.GoTrueAdminMFAApi.deleteFactor": [Object], - "@supabase/supabase-js.GoTrueAdminMFAApi.listFactors": [Object], - "@supabase/supabase-js.GoTrueAdminOAuthApi.createClient": [Object], - "@supabase/supabase-js.GoTrueAdminOAuthApi.deleteClient": [Object], - "@supabase/supabase-js.GoTrueAdminOAuthApi.getClient": [Object], - "@supabase/supabase-js.GoTrueAdminOAuthApi.listClients": [Object], - "@supabase/supabase-js.GoTrueAdminOAuthApi.regenerateClientSecret": [Object], - "@supabase/supabase-js.GoTrueAdminOAuthApi.updateClient": [Object], - "@supabase/supabase-js.GoTrueAdminPasskeyApi.deletePasskey": [Object], - "@supabase/supabase-js.GoTrueAdminPasskeyApi.listPasskeys": [Object], - "@supabase/supabase-js.GoTrueClient._refreshSession": [Object], - "@supabase/supabase-js.GoTrueClient._setSession": [Object], - "@supabase/supabase-js.GoTrueClient._signOut": [Object], - "@supabase/supabase-js.GoTrueClient._updateUser": [Object], - "@supabase/supabase-js.GoTrueClient.constructor": [Object], - "@supabase/supabase-js.GoTrueClient.dispose": [Object], - "@supabase/supabase-js.GoTrueClient.exchangeCodeForSession": [Object], - "@supabase/supabase-js.GoTrueClient.getClaims": [Object], - "@supabase/supabase-js.GoTrueClient.getSession": [Object], - "@supabase/supabase-js.GoTrueClient.getUser": [Object], - "@supabase/supabase-js.GoTrueClient.getUserIdentities": [Object], - "@supabase/supabase-js.GoTrueClient.initialize": [Object], - "@supabase/supabase-js.GoTrueClient.isThrowOnErrorEnabled": [Object], - "@supabase/supabase-js.GoTrueClient.linkIdentity": [Object], - "@supabase/supabase-js.GoTrueClient.onAuthStateChange": [Object], - "@supabase/supabase-js.GoTrueClient.reauthenticate": [Object], - "@supabase/supabase-js.GoTrueClient.refreshSession": [Object], - "@supabase/supabase-js.GoTrueClient.registerPasskey": [Object], - "@supabase/supabase-js.GoTrueClient.resend": [Object], - "@supabase/supabase-js.GoTrueClient.resetPasswordForEmail": [Object], - "@supabase/supabase-js.GoTrueClient.setSession": [Object], - "@supabase/supabase-js.GoTrueClient.signInAnonymously": [Object], - "@supabase/supabase-js.GoTrueClient.signInWithIdToken": [Object], - "@supabase/supabase-js.GoTrueClient.signInWithOAuth": [Object], - "@supabase/supabase-js.GoTrueClient.signInWithOtp": [Object], - "@supabase/supabase-js.GoTrueClient.signInWithPasskey": [Object], - "@supabase/supabase-js.GoTrueClient.signInWithPassword": [Object], - "@supabase/supabase-js.GoTrueClient.signInWithSSO": [Object], - "@supabase/supabase-js.GoTrueClient.signInWithWeb3": [Object], - "@supabase/supabase-js.GoTrueClient.signOut": [Object], - "@supabase/supabase-js.GoTrueClient.signUp": [Object], - "@supabase/supabase-js.GoTrueClient.startAutoRefresh": [Object], - "@supabase/supabase-js.GoTrueClient.stopAutoRefresh": [Object], - "@supabase/supabase-js.GoTrueClient.unlinkIdentity": [Object], - "@supabase/supabase-js.GoTrueClient.updateUser": [Object], - "@supabase/supabase-js.GoTrueClient.verifyOtp": [Object], - "@supabase/supabase-js.GoTrueMFAApi.challenge": [Object], - "@supabase/supabase-js.GoTrueMFAApi.challengeAndVerify": [Object], - "@supabase/supabase-js.GoTrueMFAApi.enroll": [Object], - "@supabase/supabase-js.GoTrueMFAApi.getAuthenticatorAssuranceLevel": [Object], - "@supabase/supabase-js.GoTrueMFAApi.listFactors": [Object], - "@supabase/supabase-js.GoTrueMFAApi.unenroll": [Object], - "@supabase/supabase-js.GoTrueMFAApi.verify": [Object], - "@supabase/supabase-js.NavigatorLockAcquireTimeoutError.constructor": [Object], - "@supabase/supabase-js.PostgrestBuilder.constructor": [Object], - "@supabase/supabase-js.PostgrestBuilder.overrideTypes": [Object], - "@supabase/supabase-js.PostgrestBuilder.retry": [Object], - "@supabase/supabase-js.PostgrestBuilder.returns": [Object], - "@supabase/supabase-js.PostgrestBuilder.setHeader": [Object], - "@supabase/supabase-js.PostgrestBuilder.stripNulls": [Object], - "@supabase/supabase-js.PostgrestBuilder.then": [Object], - "@supabase/supabase-js.PostgrestBuilder.throwOnError": [Object], - "@supabase/supabase-js.PostgrestError.constructor": [Object], - "@supabase/supabase-js.PostgrestError.toJSON": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.abortSignal": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.constructor": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.containedBy": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.contains": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.csv": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.eq": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.explain": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.filter": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.geojson": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.gt": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.gte": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.ilike": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.ilikeAllOf": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.ilikeAnyOf": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.in": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.is": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.isDistinct": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.like": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.likeAllOf": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.likeAnyOf": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.limit": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.lt": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.lte": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.match": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.maxAffected": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.maybeSingle": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.neq": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.not": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.notIn": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.or": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.order": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.overlaps": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.overrideTypes": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.range": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.rangeAdjacent": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.rangeGt": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.rangeGte": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.rangeLt": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.rangeLte": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.regexIMatch": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.regexMatch": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.retry": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.returns": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.rollback": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.select": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.setHeader": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.single": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.stripNulls": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.textSearch": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.then": [Object], - "@supabase/supabase-js.PostgrestFilterBuilder.throwOnError": [Object], - "@supabase/supabase-js.PostgrestQueryBuilder.constructor": [Object], - "@supabase/supabase-js.PostgrestQueryBuilder.delete": [Object], - "@supabase/supabase-js.PostgrestQueryBuilder.insert": [Object], - "@supabase/supabase-js.PostgrestQueryBuilder.select": [Object], - "@supabase/supabase-js.PostgrestQueryBuilder.update": [Object], - "@supabase/supabase-js.PostgrestQueryBuilder.upsert": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.abortSignal": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.constructor": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.csv": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.explain": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.geojson": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.limit": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.maxAffected": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.maybeSingle": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.order": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.overrideTypes": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.range": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.retry": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.returns": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.rollback": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.select": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.setHeader": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.single": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.stripNulls": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.then": [Object], - "@supabase/supabase-js.PostgrestTransformBuilder.throwOnError": [Object], - "@supabase/supabase-js.RealtimeChannel.constructor": [Object], - "@supabase/supabase-js.RealtimeChannel.copyBindings": [Object], - "@supabase/supabase-js.RealtimeChannel.httpSend": [Object], - "@supabase/supabase-js.RealtimeChannel.on": [Object], - "@supabase/supabase-js.RealtimeChannel.presenceState": [Object], - "@supabase/supabase-js.RealtimeChannel.send": [Object], - "@supabase/supabase-js.RealtimeChannel.subscribe": [Object], - "@supabase/supabase-js.RealtimeChannel.teardown": [Object], - "@supabase/supabase-js.RealtimeChannel.track": [Object], - "@supabase/supabase-js.RealtimeChannel.unsubscribe": [Object], - "@supabase/supabase-js.RealtimeChannel.untrack": [Object], - "@supabase/supabase-js.RealtimeChannel.updateJoinPayload": [Object], - "@supabase/supabase-js.RealtimeClient.channel": [Object], - "@supabase/supabase-js.RealtimeClient.connect": [Object], - "@supabase/supabase-js.RealtimeClient.connectionState": [Object], - "@supabase/supabase-js.RealtimeClient.constructor": [Object], - "@supabase/supabase-js.RealtimeClient.disconnect": [Object], - "@supabase/supabase-js.RealtimeClient.endpointURL": [Object], - "@supabase/supabase-js.RealtimeClient.getChannels": [Object], - "@supabase/supabase-js.RealtimeClient.isConnected": [Object], - "@supabase/supabase-js.RealtimeClient.isConnecting": [Object], - "@supabase/supabase-js.RealtimeClient.isDisconnecting": [Object], - "@supabase/supabase-js.RealtimeClient.log": [Object], - "@supabase/supabase-js.RealtimeClient.onHeartbeat": [Object], - "@supabase/supabase-js.RealtimeClient.push": [Object], - "@supabase/supabase-js.RealtimeClient.removeAllChannels": [Object], - "@supabase/supabase-js.RealtimeClient.removeChannel": [Object], - "@supabase/supabase-js.RealtimeClient.sendHeartbeat": [Object], - "@supabase/supabase-js.RealtimeClient.setAuth": [Object], - "@supabase/supabase-js.RealtimePresence.constructor": [Object], - "@supabase/supabase-js.StorageApiError.constructor": [Object], - "@supabase/supabase-js.StorageApiError.toJSON": [Object], - "@supabase/supabase-js.SupabaseClient.channel": [Object], - "@supabase/supabase-js.SupabaseClient.constructor": [Object], - "@supabase/supabase-js.SupabaseClient.from": [Object], - "@supabase/supabase-js.SupabaseClient.getChannels": [Object], - "@supabase/supabase-js.SupabaseClient.removeAllChannels": [Object], - "@supabase/supabase-js.SupabaseClient.removeChannel": [Object], - "@supabase/supabase-js.SupabaseClient.rpc": [Object], - "@supabase/supabase-js.SupabaseClient.schema": [Object], - "@supabase/supabase-js.WebSocketFactory.getWebSocketConstructor": [Object], - "@supabase/supabase-js.WebSocketFactory.isWebSocketSupported": [Object], - "@supabase/supabase-js.WebSocketLike.addEventListener": [Object], - "@supabase/supabase-js.WebSocketLike.close": [Object], - "@supabase/supabase-js.WebSocketLike.removeEventListener": [Object], - "@supabase/supabase-js.WebSocketLike.send": [Object], - "@supabase/supabase-js.WebSocketLikeConstructor.constructor": [Object], - "@supabase/supabase-js.createClient": [Object], - "@supabase/supabase-js.isAuthApiError": [Object], - "@supabase/supabase-js.isAuthError": [Object], - "@supabase/supabase-js.isAuthImplicitGrantRedirectError": [Object], - "@supabase/supabase-js.isAuthPKCECodeVerifierMissingError": [Object], - "@supabase/supabase-js.isAuthRefreshDiscardedError": [Object], - "@supabase/supabase-js.isAuthRetryableFetchError": [Object], - "@supabase/supabase-js.isAuthSessionMissingError": [Object], - "@supabase/supabase-js.isAuthWeakPasswordError": [Object], - "@supabase/supabase-js.navigatorLock": [Object], - "@supabase/supabase-js.processLock": [Object], - }, - "variables": [Object], - }, -} -`; diff --git a/apps/docs/scripts/__snapshots__/build-reference-content.v2.json b/apps/docs/scripts/__snapshots__/build-reference-content.v2.json new file mode 100644 index 00000000000..d7d17c8dd43 --- /dev/null +++ b/apps/docs/scripts/__snapshots__/build-reference-content.v2.json @@ -0,0 +1,98066 @@ +{ + "bySlug": { + "introduction": { + "id": "introduction", + "title": "Introduction", + "slug": "introduction", + "type": "markdown" + }, + "installing": { + "id": "installing", + "title": "Installing", + "slug": "installing", + "type": "markdown" + }, + "initializing": { + "id": "initializing", + "title": "Initializing", + "slug": "initializing", + "type": "function" + }, + "typescript-support": { + "id": "typescript-support", + "title": "TypeScript support", + "slug": "typescript-support", + "type": "markdown" + }, + "database": { + "type": "category", + "title": "Database" + }, + "delete": { + "id": "delete", + "title": "delete", + "slug": "delete", + "product": "database", + "type": "function" + }, + "from": { + "id": "from", + "title": "from", + "slug": "from", + "product": "database", + "type": "function" + }, + "geojson": { + "id": "geojson", + "title": "geojson", + "slug": "geojson", + "product": "database", + "type": "function" + }, + "insert": { + "id": "insert", + "title": "insert", + "slug": "insert", + "product": "database", + "type": "function" + }, + "maxaffected": { + "id": "maxaffected", + "title": "maxAffected", + "slug": "maxaffected", + "product": "database", + "type": "function" + }, + "retry": { + "id": "retry", + "title": "retry", + "slug": "retry", + "product": "database", + "type": "function" + }, + "returns": { + "id": "returns", + "title": "returns", + "slug": "returns", + "product": "database", + "type": "function" + }, + "rollback": { + "id": "rollback", + "title": "rollback", + "slug": "rollback", + "product": "database", + "type": "function" + }, + "rpc": { + "id": "rpc", + "title": "rpc", + "slug": "rpc", + "product": "database", + "type": "function" + }, + "schema": { + "id": "schema", + "title": "schema", + "slug": "schema", + "product": "database", + "type": "function" + }, + "select": { + "id": "select", + "title": "select", + "slug": "select", + "product": "database", + "type": "function" + }, + "setheader": { + "id": "setheader", + "title": "setHeader", + "slug": "setheader", + "product": "database", + "type": "function" + }, + "throwonerror": { + "id": "throwonerror", + "title": "throwOnError", + "slug": "throwonerror", + "product": "database", + "type": "function" + }, + "update": { + "id": "update", + "title": "update", + "slug": "update", + "product": "database", + "type": "function" + }, + "upsert": { + "id": "upsert", + "title": "upsert", + "slug": "upsert", + "product": "database", + "type": "function" + }, + "using-filters": { + "id": "using-filters", + "title": "Using Filters", + "slug": "using-filters", + "type": "function" + }, + "using-filters-containedby": { + "id": "using-filters-containedby", + "title": "containedBy", + "slug": "using-filters-containedby", + "product": "database", + "type": "function" + }, + "using-filters-contains": { + "id": "using-filters-contains", + "title": "contains", + "slug": "using-filters-contains", + "product": "database", + "type": "function" + }, + "using-filters-eq": { + "id": "using-filters-eq", + "title": "eq", + "slug": "using-filters-eq", + "product": "database", + "type": "function" + }, + "using-filters-filter": { + "id": "using-filters-filter", + "title": "filter", + "slug": "using-filters-filter", + "product": "database", + "type": "function" + }, + "using-filters-gt": { + "id": "using-filters-gt", + "title": "gt", + "slug": "using-filters-gt", + "product": "database", + "type": "function" + }, + "using-filters-gte": { + "id": "using-filters-gte", + "title": "gte", + "slug": "using-filters-gte", + "product": "database", + "type": "function" + }, + "using-filters-ilike": { + "id": "using-filters-ilike", + "title": "ilike", + "slug": "using-filters-ilike", + "product": "database", + "type": "function" + }, + "using-filters-ilikeallof": { + "id": "using-filters-ilikeallof", + "title": "ilikeAllOf", + "slug": "using-filters-ilikeallof", + "product": "database", + "type": "function" + }, + "using-filters-ilikeanyof": { + "id": "using-filters-ilikeanyof", + "title": "ilikeAnyOf", + "slug": "using-filters-ilikeanyof", + "product": "database", + "type": "function" + }, + "using-filters-in": { + "id": "using-filters-in", + "title": "in", + "slug": "using-filters-in", + "product": "database", + "type": "function" + }, + "using-filters-is": { + "id": "using-filters-is", + "title": "is", + "slug": "using-filters-is", + "product": "database", + "type": "function" + }, + "using-filters-like": { + "id": "using-filters-like", + "title": "like", + "slug": "using-filters-like", + "product": "database", + "type": "function" + }, + "using-filters-likeallof": { + "id": "using-filters-likeallof", + "title": "likeAllOf", + "slug": "using-filters-likeallof", + "product": "database", + "type": "function" + }, + "using-filters-likeanyof": { + "id": "using-filters-likeanyof", + "title": "likeAnyOf", + "slug": "using-filters-likeanyof", + "product": "database", + "type": "function" + }, + "using-filters-lt": { + "id": "using-filters-lt", + "title": "lt", + "slug": "using-filters-lt", + "product": "database", + "type": "function" + }, + "using-filters-lte": { + "id": "using-filters-lte", + "title": "lte", + "slug": "using-filters-lte", + "product": "database", + "type": "function" + }, + "using-filters-match": { + "id": "using-filters-match", + "title": "match", + "slug": "using-filters-match", + "product": "database", + "type": "function" + }, + "using-filters-neq": { + "id": "using-filters-neq", + "title": "neq", + "slug": "using-filters-neq", + "product": "database", + "type": "function" + }, + "using-filters-not": { + "id": "using-filters-not", + "title": "not", + "slug": "using-filters-not", + "product": "database", + "type": "function" + }, + "using-filters-or": { + "id": "using-filters-or", + "title": "or", + "slug": "using-filters-or", + "product": "database", + "type": "function" + }, + "using-filters-overlaps": { + "id": "using-filters-overlaps", + "title": "overlaps", + "slug": "using-filters-overlaps", + "product": "database", + "type": "function" + }, + "using-filters-rangeadjacent": { + "id": "using-filters-rangeadjacent", + "title": "rangeAdjacent", + "slug": "using-filters-rangeadjacent", + "product": "database", + "type": "function" + }, + "using-filters-rangegt": { + "id": "using-filters-rangegt", + "title": "rangeGt", + "slug": "using-filters-rangegt", + "product": "database", + "type": "function" + }, + "using-filters-rangegte": { + "id": "using-filters-rangegte", + "title": "rangeGte", + "slug": "using-filters-rangegte", + "product": "database", + "type": "function" + }, + "using-filters-rangelt": { + "id": "using-filters-rangelt", + "title": "rangeLt", + "slug": "using-filters-rangelt", + "product": "database", + "type": "function" + }, + "using-filters-rangelte": { + "id": "using-filters-rangelte", + "title": "rangeLte", + "slug": "using-filters-rangelte", + "product": "database", + "type": "function" + }, + "using-filters-textsearch": { + "id": "using-filters-textsearch", + "title": "textSearch", + "slug": "using-filters-textsearch", + "product": "database", + "type": "function" + }, + "using-modifiers": { + "id": "using-modifiers", + "title": "Using modifiers", + "slug": "using-modifiers", + "type": "function" + }, + "using-modifiers-abortsignal": { + "id": "using-modifiers-abortsignal", + "title": "abortSignal", + "slug": "using-modifiers-abortsignal", + "product": "database", + "type": "function" + }, + "using-modifiers-csv": { + "id": "using-modifiers-csv", + "title": "csv", + "slug": "using-modifiers-csv", + "product": "database", + "type": "function" + }, + "using-modifiers-explain": { + "id": "using-modifiers-explain", + "title": "explain", + "slug": "using-modifiers-explain", + "product": "database", + "type": "function" + }, + "using-modifiers-limit": { + "id": "using-modifiers-limit", + "title": "limit", + "slug": "using-modifiers-limit", + "product": "database", + "type": "function" + }, + "using-modifiers-maybesingle": { + "id": "using-modifiers-maybesingle", + "title": "maybeSingle", + "slug": "using-modifiers-maybesingle", + "product": "database", + "type": "function" + }, + "using-modifiers-order": { + "id": "using-modifiers-order", + "title": "order", + "slug": "using-modifiers-order", + "product": "database", + "type": "function" + }, + "using-modifiers-overridetypes": { + "id": "using-modifiers-overridetypes", + "title": "overrideTypes", + "slug": "using-modifiers-overridetypes", + "product": "database", + "type": "function" + }, + "using-modifiers-range": { + "id": "using-modifiers-range", + "title": "range", + "slug": "using-modifiers-range", + "product": "database", + "type": "function" + }, + "using-modifiers-returns": { + "id": "using-modifiers-returns", + "title": "returns", + "slug": "using-modifiers-returns", + "product": "database", + "type": "function" + }, + "using-modifiers-select": { + "id": "using-modifiers-select", + "title": "select", + "slug": "using-modifiers-select", + "product": "database", + "type": "function" + }, + "using-modifiers-single": { + "id": "using-modifiers-single", + "title": "single", + "slug": "using-modifiers-single", + "product": "database", + "type": "function" + }, + "using-modifiers-stripnulls": { + "id": "using-modifiers-stripnulls", + "title": "stripNulls", + "slug": "using-modifiers-stripnulls", + "product": "database", + "type": "function" + }, + "auth": { + "id": "auth", + "title": "Overview", + "slug": "auth", + "type": "function" + }, + "auth-dispose": { + "id": "auth-dispose", + "title": "dispose", + "slug": "auth-dispose", + "product": "auth", + "type": "function" + }, + "auth-exchangecodeforsession": { + "id": "auth-exchangecodeforsession", + "title": "exchangeCodeForSession", + "slug": "auth-exchangecodeforsession", + "product": "auth", + "type": "function" + }, + "auth-getclaims": { + "id": "auth-getclaims", + "title": "getClaims", + "slug": "auth-getclaims", + "product": "auth", + "type": "function" + }, + "auth-getsession": { + "id": "auth-getsession", + "title": "getSession", + "slug": "auth-getsession", + "product": "auth", + "type": "function" + }, + "auth-getuser": { + "id": "auth-getuser", + "title": "getUser", + "slug": "auth-getuser", + "product": "auth", + "type": "function" + }, + "auth-getuseridentities": { + "id": "auth-getuseridentities", + "title": "getUserIdentities", + "slug": "auth-getuseridentities", + "product": "auth", + "type": "function" + }, + "auth-initialize": { + "id": "auth-initialize", + "title": "initialize", + "slug": "auth-initialize", + "product": "auth", + "type": "function" + }, + "auth-linkidentity": { + "id": "auth-linkidentity", + "title": "linkIdentity", + "slug": "auth-linkidentity", + "product": "auth", + "type": "function" + }, + "auth-onauthstatechange": { + "id": "auth-onauthstatechange", + "title": "onAuthStateChange", + "slug": "auth-onauthstatechange", + "product": "auth", + "type": "function" + }, + "auth-reauthenticate": { + "id": "auth-reauthenticate", + "title": "reauthenticate", + "slug": "auth-reauthenticate", + "product": "auth", + "type": "function" + }, + "auth-refreshsession": { + "id": "auth-refreshsession", + "title": "refreshSession", + "slug": "auth-refreshsession", + "product": "auth", + "type": "function" + }, + "auth-registerpasskey": { + "id": "auth-registerpasskey", + "title": "registerPasskey", + "slug": "auth-registerpasskey", + "product": "auth", + "type": "function" + }, + "auth-resend": { + "id": "auth-resend", + "title": "resend", + "slug": "auth-resend", + "product": "auth", + "type": "function" + }, + "auth-resetpasswordforemail": { + "id": "auth-resetpasswordforemail", + "title": "resetPasswordForEmail", + "slug": "auth-resetpasswordforemail", + "product": "auth", + "type": "function" + }, + "auth-setsession": { + "id": "auth-setsession", + "title": "setSession", + "slug": "auth-setsession", + "product": "auth", + "type": "function" + }, + "auth-signinanonymously": { + "id": "auth-signinanonymously", + "title": "signInAnonymously", + "slug": "auth-signinanonymously", + "product": "auth", + "type": "function" + }, + "auth-signinwithidtoken": { + "id": "auth-signinwithidtoken", + "title": "signInWithIdToken", + "slug": "auth-signinwithidtoken", + "product": "auth", + "type": "function" + }, + "auth-signinwithoauth": { + "id": "auth-signinwithoauth", + "title": "signInWithOAuth", + "slug": "auth-signinwithoauth", + "product": "auth", + "type": "function" + }, + "auth-signinwithotp": { + "id": "auth-signinwithotp", + "title": "signInWithOtp", + "slug": "auth-signinwithotp", + "product": "auth", + "type": "function" + }, + "auth-signinwithpasskey": { + "id": "auth-signinwithpasskey", + "title": "signInWithPasskey", + "slug": "auth-signinwithpasskey", + "product": "auth", + "type": "function" + }, + "auth-signinwithpassword": { + "id": "auth-signinwithpassword", + "title": "signInWithPassword", + "slug": "auth-signinwithpassword", + "product": "auth", + "type": "function" + }, + "auth-signinwithsso": { + "id": "auth-signinwithsso", + "title": "signInWithSSO", + "slug": "auth-signinwithsso", + "product": "auth", + "type": "function" + }, + "auth-signinwithweb3": { + "id": "auth-signinwithweb3", + "title": "signInWithWeb3", + "slug": "auth-signinwithweb3", + "product": "auth", + "type": "function" + }, + "auth-signout": { + "id": "auth-signout", + "title": "signOut", + "slug": "auth-signout", + "product": "auth", + "type": "function" + }, + "auth-signup": { + "id": "auth-signup", + "title": "signUp", + "slug": "auth-signup", + "product": "auth", + "type": "function" + }, + "auth-startautorefresh": { + "id": "auth-startautorefresh", + "title": "startAutoRefresh", + "slug": "auth-startautorefresh", + "product": "auth", + "type": "function" + }, + "auth-stopautorefresh": { + "id": "auth-stopautorefresh", + "title": "stopAutoRefresh", + "slug": "auth-stopautorefresh", + "product": "auth", + "type": "function" + }, + "auth-unlinkidentity": { + "id": "auth-unlinkidentity", + "title": "unlinkIdentity", + "slug": "auth-unlinkidentity", + "product": "auth", + "type": "function" + }, + "auth-updateuser": { + "id": "auth-updateuser", + "title": "updateUser", + "slug": "auth-updateuser", + "product": "auth", + "type": "function" + }, + "auth-verifyotp": { + "id": "auth-verifyotp", + "title": "verifyOtp", + "slug": "auth-verifyotp", + "product": "auth", + "type": "function" + }, + "auth-admin": { + "id": "auth-admin", + "title": "Overview", + "slug": "auth-admin", + "type": "function" + }, + "auth-admin-createprovider": { + "id": "auth-admin-createprovider", + "title": "createProvider", + "slug": "auth-admin-createprovider", + "product": "auth", + "type": "function" + }, + "auth-admin-createuser": { + "id": "auth-admin-createuser", + "title": "createUser", + "slug": "auth-admin-createuser", + "product": "auth", + "type": "function" + }, + "auth-admin-deletefactor": { + "id": "auth-admin-deletefactor", + "title": "deleteFactor", + "slug": "auth-admin-deletefactor", + "product": "auth", + "type": "function" + }, + "auth-admin-deleteprovider": { + "id": "auth-admin-deleteprovider", + "title": "deleteProvider", + "slug": "auth-admin-deleteprovider", + "product": "auth", + "type": "function" + }, + "auth-admin-deleteuser": { + "id": "auth-admin-deleteuser", + "title": "deleteUser", + "slug": "auth-admin-deleteuser", + "product": "auth", + "type": "function" + }, + "auth-admin-generatelink": { + "id": "auth-admin-generatelink", + "title": "generateLink", + "slug": "auth-admin-generatelink", + "product": "auth", + "type": "function" + }, + "auth-admin-getprovider": { + "id": "auth-admin-getprovider", + "title": "getProvider", + "slug": "auth-admin-getprovider", + "product": "auth", + "type": "function" + }, + "auth-admin-getuserbyid": { + "id": "auth-admin-getuserbyid", + "title": "getUserById", + "slug": "auth-admin-getuserbyid", + "product": "auth", + "type": "function" + }, + "auth-admin-inviteuserbyemail": { + "id": "auth-admin-inviteuserbyemail", + "title": "inviteUserByEmail", + "slug": "auth-admin-inviteuserbyemail", + "product": "auth", + "type": "function" + }, + "auth-admin-listfactors": { + "id": "auth-admin-listfactors", + "title": "listFactors", + "slug": "auth-admin-listfactors", + "product": "auth", + "type": "function" + }, + "auth-admin-listproviders": { + "id": "auth-admin-listproviders", + "title": "listProviders", + "slug": "auth-admin-listproviders", + "product": "auth", + "type": "function" + }, + "auth-admin-listusers": { + "id": "auth-admin-listusers", + "title": "listUsers", + "slug": "auth-admin-listusers", + "product": "auth", + "type": "function" + }, + "auth-admin-signout": { + "id": "auth-admin-signout", + "title": "signOut", + "slug": "auth-admin-signout", + "product": "auth", + "type": "function" + }, + "auth-admin-updateprovider": { + "id": "auth-admin-updateprovider", + "title": "updateProvider", + "slug": "auth-admin-updateprovider", + "product": "auth", + "type": "function" + }, + "auth-admin-updateuserbyid": { + "id": "auth-admin-updateuserbyid", + "title": "updateUserById", + "slug": "auth-admin-updateuserbyid", + "product": "auth", + "type": "function" + }, + "auth-mfa": { + "id": "auth-mfa", + "title": "Auth MFA", + "slug": "auth-mfa", + "type": "function" + }, + "auth-mfa-challenge": { + "id": "auth-mfa-challenge", + "title": "challenge", + "slug": "auth-mfa-challenge", + "product": "auth", + "type": "function" + }, + "auth-mfa-challengeandverify": { + "id": "auth-mfa-challengeandverify", + "title": "challengeAndVerify", + "slug": "auth-mfa-challengeandverify", + "product": "auth", + "type": "function" + }, + "auth-mfa-enroll": { + "id": "auth-mfa-enroll", + "title": "enroll", + "slug": "auth-mfa-enroll", + "product": "auth", + "type": "function" + }, + "auth-mfa-getauthenticatorassurancelevel": { + "id": "auth-mfa-getauthenticatorassurancelevel", + "title": "getAuthenticatorAssuranceLevel", + "slug": "auth-mfa-getauthenticatorassurancelevel", + "product": "auth", + "type": "function" + }, + "auth-mfa-listfactors": { + "id": "auth-mfa-listfactors", + "title": "listFactors", + "slug": "auth-mfa-listfactors", + "product": "auth", + "type": "function" + }, + "auth-mfa-unenroll": { + "id": "auth-mfa-unenroll", + "title": "unenroll", + "slug": "auth-mfa-unenroll", + "product": "auth", + "type": "function" + }, + "auth-mfa-verify": { + "id": "auth-mfa-verify", + "title": "verify", + "slug": "auth-mfa-verify", + "product": "auth", + "type": "function" + }, + "auth-passkey": { + "id": "auth-passkey", + "title": "Auth Passkey", + "slug": "auth-passkey", + "type": "function" + }, + "auth-passkey-delete": { + "id": "auth-passkey-delete", + "title": "delete", + "slug": "auth-passkey-delete", + "product": "auth", + "type": "function" + }, + "auth-passkey-list": { + "id": "auth-passkey-list", + "title": "list", + "slug": "auth-passkey-list", + "product": "auth", + "type": "function" + }, + "auth-passkey-startauthentication": { + "id": "auth-passkey-startauthentication", + "title": "startAuthentication", + "slug": "auth-passkey-startauthentication", + "product": "auth", + "type": "function" + }, + "auth-passkey-startregistration": { + "id": "auth-passkey-startregistration", + "title": "startRegistration", + "slug": "auth-passkey-startregistration", + "product": "auth", + "type": "function" + }, + "auth-passkey-update": { + "id": "auth-passkey-update", + "title": "update", + "slug": "auth-passkey-update", + "product": "auth", + "type": "function" + }, + "auth-passkey-verifyauthentication": { + "id": "auth-passkey-verifyauthentication", + "title": "verifyAuthentication", + "slug": "auth-passkey-verifyauthentication", + "product": "auth", + "type": "function" + }, + "auth-passkey-verifyregistration": { + "id": "auth-passkey-verifyregistration", + "title": "verifyRegistration", + "slug": "auth-passkey-verifyregistration", + "product": "auth", + "type": "function" + }, + "oauth-admin": { + "id": "oauth-admin", + "title": "OAuth Admin", + "slug": "oauth-admin", + "type": "function" + }, + "oauth-admin-createclient": { + "id": "oauth-admin-createclient", + "title": "createClient", + "slug": "oauth-admin-createclient", + "product": "auth", + "type": "function" + }, + "oauth-admin-deleteclient": { + "id": "oauth-admin-deleteclient", + "title": "deleteClient", + "slug": "oauth-admin-deleteclient", + "product": "auth", + "type": "function" + }, + "oauth-admin-getclient": { + "id": "oauth-admin-getclient", + "title": "getClient", + "slug": "oauth-admin-getclient", + "product": "auth", + "type": "function" + }, + "oauth-admin-listclients": { + "id": "oauth-admin-listclients", + "title": "listClients", + "slug": "oauth-admin-listclients", + "product": "auth", + "type": "function" + }, + "oauth-admin-regenerateclientsecret": { + "id": "oauth-admin-regenerateclientsecret", + "title": "regenerateClientSecret", + "slug": "oauth-admin-regenerateclientsecret", + "product": "auth", + "type": "function" + }, + "oauth-admin-updateclient": { + "id": "oauth-admin-updateclient", + "title": "updateClient", + "slug": "oauth-admin-updateclient", + "product": "auth", + "type": "function" + }, + "oauth-server": { + "id": "oauth-server", + "title": "OAuth Server", + "slug": "oauth-server", + "type": "function" + }, + "oauth-server-approveauthorization": { + "id": "oauth-server-approveauthorization", + "title": "approveAuthorization", + "slug": "oauth-server-approveauthorization", + "product": "auth", + "type": "function" + }, + "oauth-server-denyauthorization": { + "id": "oauth-server-denyauthorization", + "title": "denyAuthorization", + "slug": "oauth-server-denyauthorization", + "product": "auth", + "type": "function" + }, + "oauth-server-getauthorizationdetails": { + "id": "oauth-server-getauthorizationdetails", + "title": "getAuthorizationDetails", + "slug": "oauth-server-getauthorizationdetails", + "product": "auth", + "type": "function" + }, + "oauth-server-listgrants": { + "id": "oauth-server-listgrants", + "title": "listGrants", + "slug": "oauth-server-listgrants", + "product": "auth", + "type": "function" + }, + "oauth-server-revokegrant": { + "id": "oauth-server-revokegrant", + "title": "revokeGrant", + "slug": "oauth-server-revokegrant", + "product": "auth", + "type": "function" + }, + "passkey-admin": { + "id": "passkey-admin", + "title": "Passkey admin", + "slug": "passkey-admin", + "type": "function" + }, + "passkey-admin-deletepasskey": { + "id": "passkey-admin-deletepasskey", + "title": "deletePasskey", + "slug": "passkey-admin-deletepasskey", + "product": "auth", + "type": "function" + }, + "passkey-admin-listpasskeys": { + "id": "passkey-admin-listpasskeys", + "title": "listPasskeys", + "slug": "passkey-admin-listpasskeys", + "product": "auth", + "type": "function" + }, + "functions": { + "type": "category", + "title": "Edge Functions" + }, + "functions-corsheaders": { + "id": "functions-corsheaders", + "title": "corsHeaders", + "slug": "functions-corsheaders", + "product": "edge-functions", + "type": "function" + }, + "functions-invoke": { + "id": "functions-invoke", + "title": "invoke", + "slug": "functions-invoke", + "product": "edge-functions", + "type": "function" + }, + "functions-setauth": { + "id": "functions-setauth", + "title": "setAuth", + "slug": "functions-setauth", + "product": "edge-functions", + "type": "function" + }, + "realtime": { + "type": "category", + "title": "Realtime" + }, + "channel": { + "id": "channel", + "title": "channel", + "slug": "channel", + "product": "realtime", + "type": "function" + }, + "connect": { + "id": "connect", + "title": "connect", + "slug": "connect", + "product": "realtime", + "type": "function" + }, + "connectionstate": { + "id": "connectionstate", + "title": "connectionState", + "slug": "connectionstate", + "product": "realtime", + "type": "function" + }, + "disconnect": { + "id": "disconnect", + "title": "disconnect", + "slug": "disconnect", + "product": "realtime", + "type": "function" + }, + "endpointurl": { + "id": "endpointurl", + "title": "endpointURL", + "slug": "endpointurl", + "product": "realtime", + "type": "function" + }, + "getchannels": { + "id": "getchannels", + "title": "getChannels", + "slug": "getchannels", + "product": "realtime", + "type": "function" + }, + "getwebsocketconstructor": { + "id": "getwebsocketconstructor", + "title": "getWebSocketConstructor", + "slug": "getwebsocketconstructor", + "product": "realtime", + "type": "function" + }, + "httpsend": { + "id": "httpsend", + "title": "httpSend", + "slug": "httpsend", + "product": "realtime", + "type": "function" + }, + "isconnected": { + "id": "isconnected", + "title": "isConnected", + "slug": "isconnected", + "product": "realtime", + "type": "function" + }, + "isconnecting": { + "id": "isconnecting", + "title": "isConnecting", + "slug": "isconnecting", + "product": "realtime", + "type": "function" + }, + "isdisconnecting": { + "id": "isdisconnecting", + "title": "isDisconnecting", + "slug": "isdisconnecting", + "product": "realtime", + "type": "function" + }, + "iswebsocketsupported": { + "id": "iswebsocketsupported", + "title": "isWebSocketSupported", + "slug": "iswebsocketsupported", + "product": "realtime", + "type": "function" + }, + "log": { + "id": "log", + "title": "log", + "slug": "log", + "product": "realtime", + "type": "function" + }, + "on": { + "id": "on", + "title": "on", + "slug": "on", + "product": "realtime", + "type": "function" + }, + "onheartbeat": { + "id": "onheartbeat", + "title": "onHeartbeat", + "slug": "onheartbeat", + "product": "realtime", + "type": "function" + }, + "presencestate": { + "id": "presencestate", + "title": "presenceState", + "slug": "presencestate", + "product": "realtime", + "type": "function" + }, + "push": { + "id": "push", + "title": "push", + "slug": "push", + "product": "realtime", + "type": "function" + }, + "removeallchannels": { + "id": "removeallchannels", + "title": "removeAllChannels", + "slug": "removeallchannels", + "product": "realtime", + "type": "function" + }, + "removechannel": { + "id": "removechannel", + "title": "removeChannel", + "slug": "removechannel", + "product": "realtime", + "type": "function" + }, + "send": { + "id": "send", + "title": "send", + "slug": "send", + "product": "realtime", + "type": "function" + }, + "sendheartbeat": { + "id": "sendheartbeat", + "title": "sendHeartbeat", + "slug": "sendheartbeat", + "product": "realtime", + "type": "function" + }, + "setauth": { + "id": "setauth", + "title": "setAuth", + "slug": "setauth", + "product": "realtime", + "type": "function" + }, + "subscribe": { + "id": "subscribe", + "title": "subscribe", + "slug": "subscribe", + "product": "realtime", + "type": "function" + }, + "teardown": { + "id": "teardown", + "title": "teardown", + "slug": "teardown", + "product": "realtime", + "type": "function" + }, + "track": { + "id": "track", + "title": "track", + "slug": "track", + "product": "realtime", + "type": "function" + }, + "unsubscribe": { + "id": "unsubscribe", + "title": "unsubscribe", + "slug": "unsubscribe", + "product": "realtime", + "type": "function" + }, + "untrack": { + "id": "untrack", + "title": "untrack", + "slug": "untrack", + "product": "realtime", + "type": "function" + }, + "updatejoinpayload": { + "id": "updatejoinpayload", + "title": "updateJoinPayload", + "slug": "updatejoinpayload", + "product": "realtime", + "type": "function" + }, + "storage": { + "type": "category", + "title": "Storage" + }, + "analytics-buckets": { + "id": "analytics-buckets", + "title": "Analytics Buckets", + "slug": "analytics-buckets", + "type": "function" + }, + "analytics-buckets-createbucket": { + "id": "analytics-buckets-createbucket", + "title": "createBucket", + "slug": "analytics-buckets-createbucket", + "product": "storage", + "type": "function" + }, + "analytics-buckets-deletebucket": { + "id": "analytics-buckets-deletebucket", + "title": "deleteBucket", + "slug": "analytics-buckets-deletebucket", + "product": "storage", + "type": "function" + }, + "analytics-buckets-from": { + "id": "analytics-buckets-from", + "title": "from", + "slug": "analytics-buckets-from", + "product": "storage", + "type": "function" + }, + "analytics-buckets-listbuckets": { + "id": "analytics-buckets-listbuckets", + "title": "listBuckets", + "slug": "analytics-buckets-listbuckets", + "product": "storage", + "type": "function" + }, + "file-buckets": { + "id": "file-buckets", + "title": "File Buckets", + "slug": "file-buckets", + "type": "function" + }, + "file-buckets-copy": { + "id": "file-buckets-copy", + "title": "copy", + "slug": "file-buckets-copy", + "product": "storage", + "type": "function" + }, + "file-buckets-createbucket": { + "id": "file-buckets-createbucket", + "title": "createBucket", + "slug": "file-buckets-createbucket", + "product": "storage", + "type": "function" + }, + "file-buckets-createsigneduploadurl": { + "id": "file-buckets-createsigneduploadurl", + "title": "createSignedUploadUrl", + "slug": "file-buckets-createsigneduploadurl", + "product": "storage", + "type": "function" + }, + "file-buckets-createsignedurl": { + "id": "file-buckets-createsignedurl", + "title": "createSignedUrl", + "slug": "file-buckets-createsignedurl", + "product": "storage", + "type": "function" + }, + "file-buckets-createsignedurls": { + "id": "file-buckets-createsignedurls", + "title": "createSignedUrls", + "slug": "file-buckets-createsignedurls", + "product": "storage", + "type": "function" + }, + "file-buckets-deletebucket": { + "id": "file-buckets-deletebucket", + "title": "deleteBucket", + "slug": "file-buckets-deletebucket", + "product": "storage", + "type": "function" + }, + "file-buckets-download": { + "id": "file-buckets-download", + "title": "download", + "slug": "file-buckets-download", + "product": "storage", + "type": "function" + }, + "file-buckets-emptybucket": { + "id": "file-buckets-emptybucket", + "title": "emptyBucket", + "slug": "file-buckets-emptybucket", + "product": "storage", + "type": "function" + }, + "file-buckets-exists": { + "id": "file-buckets-exists", + "title": "exists", + "slug": "file-buckets-exists", + "product": "storage", + "type": "function" + }, + "file-buckets-from": { + "id": "file-buckets-from", + "title": "from", + "slug": "file-buckets-from", + "product": "storage", + "type": "function" + }, + "file-buckets-getbucket": { + "id": "file-buckets-getbucket", + "title": "getBucket", + "slug": "file-buckets-getbucket", + "product": "storage", + "type": "function" + }, + "file-buckets-getpublicurl": { + "id": "file-buckets-getpublicurl", + "title": "getPublicUrl", + "slug": "file-buckets-getpublicurl", + "product": "storage", + "type": "function" + }, + "file-buckets-info": { + "id": "file-buckets-info", + "title": "info", + "slug": "file-buckets-info", + "product": "storage", + "type": "function" + }, + "file-buckets-list": { + "id": "file-buckets-list", + "title": "list", + "slug": "file-buckets-list", + "product": "storage", + "type": "function" + }, + "file-buckets-listbuckets": { + "id": "file-buckets-listbuckets", + "title": "listBuckets", + "slug": "file-buckets-listbuckets", + "product": "storage", + "type": "function" + }, + "file-buckets-listv2": { + "id": "file-buckets-listv2", + "title": "listV2", + "slug": "file-buckets-listv2", + "product": "storage", + "type": "function" + }, + "file-buckets-move": { + "id": "file-buckets-move", + "title": "move", + "slug": "file-buckets-move", + "product": "storage", + "type": "function" + }, + "file-buckets-remove": { + "id": "file-buckets-remove", + "title": "remove", + "slug": "file-buckets-remove", + "product": "storage", + "type": "function" + }, + "file-buckets-update": { + "id": "file-buckets-update", + "title": "update", + "slug": "file-buckets-update", + "product": "storage", + "type": "function" + }, + "file-buckets-updatebucket": { + "id": "file-buckets-updatebucket", + "title": "updateBucket", + "slug": "file-buckets-updatebucket", + "product": "storage", + "type": "function" + }, + "file-buckets-upload": { + "id": "file-buckets-upload", + "title": "upload", + "slug": "file-buckets-upload", + "product": "storage", + "type": "function" + }, + "file-buckets-uploadtosignedurl": { + "id": "file-buckets-uploadtosignedurl", + "title": "uploadToSignedUrl", + "slug": "file-buckets-uploadtosignedurl", + "product": "storage", + "type": "function" + }, + "vector-buckets": { + "id": "vector-buckets", + "title": "Vector Buckets", + "slug": "vector-buckets", + "type": "function" + }, + "vector-buckets-createbucket": { + "id": "vector-buckets-createbucket", + "title": "createBucket", + "slug": "vector-buckets-createbucket", + "product": "storage", + "type": "function" + }, + "vector-buckets-createindex": { + "id": "vector-buckets-createindex", + "title": "createIndex", + "slug": "vector-buckets-createindex", + "product": "storage", + "type": "function" + }, + "vector-buckets-deletebucket": { + "id": "vector-buckets-deletebucket", + "title": "deleteBucket", + "slug": "vector-buckets-deletebucket", + "product": "storage", + "type": "function" + }, + "vector-buckets-deleteindex": { + "id": "vector-buckets-deleteindex", + "title": "deleteIndex", + "slug": "vector-buckets-deleteindex", + "product": "storage", + "type": "function" + }, + "vector-buckets-deletevectors": { + "id": "vector-buckets-deletevectors", + "title": "deleteVectors", + "slug": "vector-buckets-deletevectors", + "product": "storage", + "type": "function" + }, + "vector-buckets-from": { + "id": "vector-buckets-from", + "title": "from", + "slug": "vector-buckets-from", + "product": "storage", + "type": "function" + }, + "vector-buckets-getbucket": { + "id": "vector-buckets-getbucket", + "title": "getBucket", + "slug": "vector-buckets-getbucket", + "product": "storage", + "type": "function" + }, + "vector-buckets-getindex": { + "id": "vector-buckets-getindex", + "title": "getIndex", + "slug": "vector-buckets-getindex", + "product": "storage", + "type": "function" + }, + "vector-buckets-getvectors": { + "id": "vector-buckets-getvectors", + "title": "getVectors", + "slug": "vector-buckets-getvectors", + "product": "storage", + "type": "function" + }, + "vector-buckets-index": { + "id": "vector-buckets-index", + "title": "index", + "slug": "vector-buckets-index", + "product": "storage", + "type": "function" + }, + "vector-buckets-listbuckets": { + "id": "vector-buckets-listbuckets", + "title": "listBuckets", + "slug": "vector-buckets-listbuckets", + "product": "storage", + "type": "function" + }, + "vector-buckets-listindexes": { + "id": "vector-buckets-listindexes", + "title": "listIndexes", + "slug": "vector-buckets-listindexes", + "product": "storage", + "type": "function" + }, + "vector-buckets-listvectors": { + "id": "vector-buckets-listvectors", + "title": "listVectors", + "slug": "vector-buckets-listvectors", + "product": "storage", + "type": "function" + }, + "vector-buckets-putvectors": { + "id": "vector-buckets-putvectors", + "title": "putVectors", + "slug": "vector-buckets-putvectors", + "product": "storage", + "type": "function" + }, + "vector-buckets-queryvectors": { + "id": "vector-buckets-queryvectors", + "title": "queryVectors", + "slug": "vector-buckets-queryvectors", + "product": "storage", + "type": "function" + } + }, + "flat": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ], + "sections": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + { + "type": "category", + "title": "Database", + "items": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + { + "id": "using-filters", + "isFunc": false, + "title": "Using filters", + "slug": "using-filters", + "product": "database", + "type": "function", + "items": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + { + "id": "using-modifiers", + "isFunc": false, + "title": "Using modifiers", + "slug": "using-modifiers", + "product": "database", + "type": "function", + "items": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + } + ] + }, + { + "type": "category", + "title": "Auth", + "items": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + { + "id": "auth-admin", + "isFunc": false, + "title": "Auth Admin", + "slug": "auth-admin", + "product": "auth", + "type": "function", + "items": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + { + "id": "auth-mfa", + "isFunc": false, + "title": "Auth MFA", + "slug": "auth-mfa", + "product": "auth", + "type": "function", + "items": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + { + "id": "auth-passkey", + "isFunc": false, + "title": "Auth Passkey", + "slug": "auth-passkey", + "product": "auth", + "type": "function", + "items": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + { + "id": "oauth-admin", + "isFunc": false, + "title": "OAuth Admin", + "slug": "oauth-admin", + "product": "auth", + "type": "function", + "items": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + { + "id": "oauth-server", + "isFunc": false, + "title": "OAuth Server", + "slug": "oauth-server", + "product": "auth", + "type": "function", + "items": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + { + "id": "passkey-admin", + "isFunc": false, + "title": "Passkey Admin", + "slug": "passkey-admin", + "product": "auth", + "type": "function", + "items": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + } + ] + }, + { + "type": "category", + "title": "Edge Functions", + "items": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + { + "type": "category", + "title": "Realtime", + "items": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + { + "type": "category", + "title": "Storage", + "items": [ + { + "id": "analytics-buckets", + "isFunc": false, + "title": "Analytics Buckets", + "slug": "analytics-buckets", + "product": "storage", + "type": "function", + "items": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + { + "id": "file-buckets", + "isFunc": false, + "title": "File Buckets", + "slug": "file-buckets", + "product": "storage", + "type": "function", + "items": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + { + "id": "vector-buckets", + "isFunc": false, + "title": "Vector Buckets", + "slug": "vector-buckets", + "product": "storage", + "type": "function", + "items": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + } + ] + } + ], + "functionsList": [ + { + "id": "initializing", + "$ref": "@supabase/supabase-js.SupabaseClient.constructor" + }, + { + "id": "delete", + "$ref": "@supabase/postgrest-js.PostgrestQueryBuilder.delete" + }, + { + "id": "from", + "$ref": "@supabase/postgrest-js.PostgrestClient.from" + }, + { + "id": "geojson", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.geojson" + }, + { + "id": "insert", + "$ref": "@supabase/postgrest-js.PostgrestQueryBuilder.insert" + }, + { + "id": "maxaffected", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.maxAffected" + }, + { + "id": "retry", + "$ref": "@supabase/postgrest-js.PostgrestBuilder.retry" + }, + { + "id": "returns", + "$ref": "@supabase/postgrest-js.PostgrestBuilder.returns" + }, + { + "id": "rollback", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.rollback" + }, + { + "id": "rpc", + "$ref": "@supabase/postgrest-js.PostgrestClient.rpc" + }, + { + "id": "schema", + "$ref": "@supabase/postgrest-js.PostgrestClient.schema" + }, + { + "id": "select", + "$ref": "@supabase/postgrest-js.PostgrestQueryBuilder.select" + }, + { + "id": "setheader", + "$ref": "@supabase/postgrest-js.PostgrestBuilder.setHeader" + }, + { + "id": "throwonerror", + "$ref": "@supabase/postgrest-js.PostgrestBuilder.throwOnError" + }, + { + "id": "update", + "$ref": "@supabase/postgrest-js.PostgrestQueryBuilder.update" + }, + { + "id": "upsert", + "$ref": "@supabase/postgrest-js.PostgrestQueryBuilder.upsert" + }, + { + "id": "using-filters", + "title": "Using Filters", + "description": "Filters allow you to only return rows that match certain conditions.\n\nFilters can be used on `select()`, `update()`, `upsert()`, and `delete()` queries.\n\nIf a Postgres function returns a table response, you can also apply filters.\n", + "examples": [ + { + "id": "applying-filters", + "name": "Applying Filters", + "description": "Filters must be applied after any of `select()`, `update()`, `upsert()`,\n`delete()`, and `rpc()` and before\n[modifiers](/docs/reference/javascript/using-modifiers).\n", + "code": "```ts\nconst { data, error } = await supabase\n .from('instruments')\n .select('name, section_id')\n .eq('name', 'violin') // Correct\n\nconst { data, error } = await supabase\n .from('instruments')\n .eq('name', 'violin') // Incorrect\n .select('name, section_id')\n```\n" + }, + { + "id": "chaining-filters", + "name": "Chaining", + "description": "Filters can be chained together to produce advanced queries. For example,\nto query cities with population between 1,000 and 10,000:\n\n```ts\nconst { data, error } = await supabase\n .from('cities')\n .select('name, country_id')\n .gte('population', 1000)\n .lt('population', 10000)\n```\n", + "code": "```ts\nconst { data, error } = await supabase\n .from('cities')\n .select('name, country_id')\n .gte('population', 1000)\n .lt('population', 10000)\n```\n" + }, + { + "id": "conditional-chaining", + "name": "Conditional Chaining", + "description": "Filters can be built up one step at a time and then executed. For example:\n\n```ts\nconst filterByName = null\nconst filterPopLow = 1000\nconst filterPopHigh = 10000\n\nlet query = supabase\n .from('cities')\n .select('name, country_id')\n\nif (filterByName) { query = query.eq('name', filterByName) }\nif (filterPopLow) { query = query.gte('population', filterPopLow) }\nif (filterPopHigh) { query = query.lt('population', filterPopHigh) }\n\nconst { data, error } = await query\n```\n", + "code": "```ts\nconst filterByName = null\nconst filterPopLow = 1000\nconst filterPopHigh = 10000\n\nlet query = supabase\n .from('cities')\n .select('name, country_id')\n\nif (filterByName) { query = query.eq('name', filterByName) }\nif (filterPopLow) { query = query.gte('population', filterPopLow) }\nif (filterPopHigh) { query = query.lt('population', filterPopHigh) }\n\nconst { data, error } = await query\n```\n" + }, + { + "id": "filter-by-value-within-json-column", + "name": "Filter by values within a JSON column", + "code": "```ts\nconst { data, error } = await supabase\n .from('users')\n .select()\n .eq('address->postcode', 90210)\n```\n", + "data": { + "sql": "```sql\ncreate table\n users (\n id int8 primary key,\n name text,\n address jsonb\n );\n\ninsert into\n users (id, name, address)\nvalues\n (1, 'Michael', '{ \"postcode\": 90210 }'),\n (2, 'Jane', null);\n```\n" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Michael\",\n \"address\": {\n \"postcode\": 90210\n }\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```\n" + }, + { + "id": "filter-referenced-tables", + "name": "Filter referenced tables", + "code": "```ts\nconst { data, error } = await supabase\n .from('orchestral_sections')\n .select(`\n name,\n instruments!inner (\n name\n )\n `)\n .eq('instruments.name', 'flute')\n```\n", + "data": { + "sql": "```sql\ncreate table\n orchestral_sections (id int8 primary key, name text);\ncreate table\n instruments (\n id int8 primary key,\n section_id int8 not null references orchestral_sections,\n name text\n );\n\ninsert into\n orchestral_sections (id, name)\nvalues\n (1, 'strings'),\n (2, 'woodwinds');\ninsert into\n instruments (id, section_id, name)\nvalues\n (1, 2, 'flute'),\n (2, 1, 'violin');\n```\n", + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"woodwinds\",\n \"characters\": [\n {\n \"name\": \"flute\"\n }\n ]\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```\n" + }, + "description": "You can filter on referenced tables in your `select()` query using dot\nnotation.\n" + } + ] + }, + { + "id": "using-filters-containedby", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.containedBy" + }, + { + "id": "using-filters-contains", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.contains" + }, + { + "id": "using-filters-eq", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.eq" + }, + { + "id": "using-filters-filter", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.filter" + }, + { + "id": "using-filters-gt", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.gt" + }, + { + "id": "using-filters-gte", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.gte" + }, + { + "id": "using-filters-ilike", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.ilike" + }, + { + "id": "using-filters-ilikeallof", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.ilikeAllOf" + }, + { + "id": "using-filters-ilikeanyof", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.ilikeAnyOf" + }, + { + "id": "using-filters-in", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.in" + }, + { + "id": "using-filters-is", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.is" + }, + { + "id": "using-filters-like", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.like" + }, + { + "id": "using-filters-likeallof", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.likeAllOf" + }, + { + "id": "using-filters-likeanyof", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.likeAnyOf" + }, + { + "id": "using-filters-lt", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.lt" + }, + { + "id": "using-filters-lte", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.lte" + }, + { + "id": "using-filters-match", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.match" + }, + { + "id": "using-filters-neq", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.neq" + }, + { + "id": "using-filters-not", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.not" + }, + { + "id": "using-filters-or", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.or" + }, + { + "id": "using-filters-overlaps", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.overlaps" + }, + { + "id": "using-filters-rangeadjacent", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeAdjacent" + }, + { + "id": "using-filters-rangegt", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeGt" + }, + { + "id": "using-filters-rangegte", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeGte" + }, + { + "id": "using-filters-rangelt", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeLt" + }, + { + "id": "using-filters-rangelte", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeLte" + }, + { + "id": "using-filters-textsearch", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.textSearch" + }, + { + "id": "using-modifiers", + "title": "Using modifiers", + "description": "Filters work on the row level—they allow you to return rows that only match certain conditions without changing the shape of the rows. Modifiers are everything that don't fit that definition—allowing you to change the format of the response (e.g., returning a CSV string).\n\nModifiers must be specified after filters. Some modifiers only apply for queries that return rows (e.g., `select()` or `rpc()` on a function that returns a table response)." + }, + { + "id": "using-modifiers-abortsignal", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.abortSignal" + }, + { + "id": "using-modifiers-csv", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.csv" + }, + { + "id": "using-modifiers-explain", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.explain" + }, + { + "id": "using-modifiers-limit", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.limit" + }, + { + "id": "using-modifiers-maybesingle", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.maybeSingle" + }, + { + "id": "using-modifiers-order", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.order" + }, + { + "id": "using-modifiers-overridetypes", + "$ref": "@supabase/postgrest-js.PostgrestBuilder.overrideTypes" + }, + { + "id": "using-modifiers-range", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.range" + }, + { + "id": "using-modifiers-returns", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.returns" + }, + { + "id": "using-modifiers-select", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.select" + }, + { + "id": "using-modifiers-single", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.single" + }, + { + "id": "using-modifiers-stripnulls", + "$ref": "@supabase/postgrest-js.PostgrestBuilder.stripNulls" + }, + { + "id": "auth", + "title": "Overview", + "notes": "- The auth methods can be accessed via the `supabase.auth` namespace.\n- By default, the supabase client sets `persistSession` to true and attempts to store the session in local storage. When using the supabase client in an environment that doesn't support local storage, you might notice the following warning message being logged:\n\n > No storage option exists to persist the session, which may result in unexpected behavior when using auth. If you want to set `persistSession` to true, please provide a storage option or you may set `persistSession` to false to disable this warning.\n\n This warning message can be safely ignored if you're not using auth on the server-side. If you are using auth and you want to set `persistSession` to true, you will need to provide a custom storage implementation that follows [this interface](https://github.com/supabase/supabase-js/blob/master/packages/core/auth-js/src/lib/types.ts#L1053).\n- Any email links and one-time passwords (OTPs) sent have a default expiry of 24 hours. We have the following [rate limits](/docs/guides/platform/going-into-prod#auth-rate-limits) in place to guard against brute force attacks.\n- The expiry of an access token can be set in the \"JWT expiry limit\" field in [your project's auth settings](/dashboard/project/_/auth/providers). A refresh token never expires and can only be used once.\n", + "examples": [ + { + "id": "create-auth-client", + "name": "Create auth client", + "isSpotlight": true, + "code": "```js\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient(supabase_url, publishable_key)\n```\n" + }, + { + "id": "create-auth-client-server-side", + "name": "Create auth client (server-side)", + "isSpotlight": false, + "code": "```js\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient(supabase_url, publishable_key, {\n auth: {\n autoRefreshToken: false,\n persistSession: false,\n detectSessionInUrl: false\n }\n})\n```\n" + } + ] + }, + { + "id": "auth-dispose", + "$ref": "@supabase/auth-js.GoTrueClient.dispose" + }, + { + "id": "auth-exchangecodeforsession", + "$ref": "@supabase/auth-js.GoTrueClient.exchangeCodeForSession" + }, + { + "id": "auth-getclaims", + "$ref": "@supabase/auth-js.GoTrueClient.getClaims" + }, + { + "id": "auth-getsession", + "$ref": "@supabase/auth-js.GoTrueClient.getSession" + }, + { + "id": "auth-getuser", + "$ref": "@supabase/auth-js.GoTrueClient.getUser" + }, + { + "id": "auth-getuseridentities", + "$ref": "@supabase/auth-js.GoTrueClient.getUserIdentities" + }, + { + "id": "auth-initialize", + "$ref": "@supabase/auth-js.GoTrueClient.initialize" + }, + { + "id": "auth-linkidentity", + "$ref": "@supabase/auth-js.GoTrueClient.linkIdentity" + }, + { + "id": "auth-onauthstatechange", + "$ref": "@supabase/auth-js.GoTrueClient.onAuthStateChange" + }, + { + "id": "auth-reauthenticate", + "$ref": "@supabase/auth-js.GoTrueClient.reauthenticate" + }, + { + "id": "auth-refreshsession", + "$ref": "@supabase/auth-js.GoTrueClient.refreshSession" + }, + { + "id": "auth-registerpasskey", + "$ref": "@supabase/auth-js.GoTrueClient.registerPasskey" + }, + { + "id": "auth-resend", + "$ref": "@supabase/auth-js.GoTrueClient.resend" + }, + { + "id": "auth-resetpasswordforemail", + "$ref": "@supabase/auth-js.GoTrueClient.resetPasswordForEmail" + }, + { + "id": "auth-setsession", + "$ref": "@supabase/auth-js.GoTrueClient.setSession" + }, + { + "id": "auth-signinanonymously", + "$ref": "@supabase/auth-js.GoTrueClient.signInAnonymously" + }, + { + "id": "auth-signinwithidtoken", + "$ref": "@supabase/auth-js.GoTrueClient.signInWithIdToken" + }, + { + "id": "auth-signinwithoauth", + "$ref": "@supabase/auth-js.GoTrueClient.signInWithOAuth" + }, + { + "id": "auth-signinwithotp", + "$ref": "@supabase/auth-js.GoTrueClient.signInWithOtp" + }, + { + "id": "auth-signinwithpasskey", + "$ref": "@supabase/auth-js.GoTrueClient.signInWithPasskey" + }, + { + "id": "auth-signinwithpassword", + "$ref": "@supabase/auth-js.GoTrueClient.signInWithPassword" + }, + { + "id": "auth-signinwithsso", + "$ref": "@supabase/auth-js.GoTrueClient.signInWithSSO" + }, + { + "id": "auth-signinwithweb3", + "$ref": "@supabase/auth-js.GoTrueClient.signInWithWeb3" + }, + { + "id": "auth-signout", + "$ref": "@supabase/auth-js.GoTrueClient.signOut" + }, + { + "id": "auth-signup", + "$ref": "@supabase/auth-js.GoTrueClient.signUp" + }, + { + "id": "auth-startautorefresh", + "$ref": "@supabase/auth-js.GoTrueClient.startAutoRefresh" + }, + { + "id": "auth-stopautorefresh", + "$ref": "@supabase/auth-js.GoTrueClient.stopAutoRefresh" + }, + { + "id": "auth-unlinkidentity", + "$ref": "@supabase/auth-js.GoTrueClient.unlinkIdentity" + }, + { + "id": "auth-updateuser", + "$ref": "@supabase/auth-js.GoTrueClient.updateUser" + }, + { + "id": "auth-verifyotp", + "$ref": "@supabase/auth-js.GoTrueClient.verifyOtp" + }, + { + "id": "auth-admin", + "title": "Overview", + "notes": "- Any method under the `supabase.auth.admin` namespace requires a `secret` key.\n- These methods are considered admin methods and should be called on a trusted server. Never expose your `secret` key in the browser.\n", + "examples": [ + { + "id": "create-auth-admin-client", + "name": "Create server-side auth client", + "isSpotlight": true, + "code": "```js\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient(supabase_url, secret_key, {\n auth: {\n autoRefreshToken: false,\n persistSession: false\n }\n})\n\n// Access auth admin api\nconst adminAuthClient = supabase.auth.admin\n```\n" + } + ] + }, + { + "id": "auth-admin-createprovider", + "$ref": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.createProvider" + }, + { + "id": "auth-admin-createuser", + "$ref": "@supabase/auth-js.GoTrueAdminApi.createUser" + }, + { + "id": "auth-admin-deletefactor", + "$ref": "@supabase/auth-js.GoTrueAdminMFAApi.deleteFactor" + }, + { + "id": "auth-admin-deleteprovider", + "$ref": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.deleteProvider" + }, + { + "id": "auth-admin-deleteuser", + "$ref": "@supabase/auth-js.GoTrueAdminApi.deleteUser" + }, + { + "id": "auth-admin-generatelink", + "$ref": "@supabase/auth-js.GoTrueAdminApi.generateLink" + }, + { + "id": "auth-admin-getprovider", + "$ref": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.getProvider" + }, + { + "id": "auth-admin-getuserbyid", + "$ref": "@supabase/auth-js.GoTrueAdminApi.getUserById" + }, + { + "id": "auth-admin-inviteuserbyemail", + "$ref": "@supabase/auth-js.GoTrueAdminApi.inviteUserByEmail" + }, + { + "id": "auth-admin-listfactors", + "$ref": "@supabase/auth-js.GoTrueAdminMFAApi.listFactors" + }, + { + "id": "auth-admin-listproviders", + "$ref": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.listProviders" + }, + { + "id": "auth-admin-listusers", + "$ref": "@supabase/auth-js.GoTrueAdminApi.listUsers" + }, + { + "id": "auth-admin-signout", + "$ref": "@supabase/auth-js.GoTrueAdminApi.signOut" + }, + { + "id": "auth-admin-updateprovider", + "$ref": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.updateProvider" + }, + { + "id": "auth-admin-updateuserbyid", + "$ref": "@supabase/auth-js.GoTrueAdminApi.updateUserById" + }, + { + "id": "auth-mfa", + "title": "Auth MFA", + "description": "This section contains methods commonly used for Multi-Factor Authentication (MFA) and are invoked behind the `supabase.auth.mfa` namespace.\n\nCurrently, there is support for time-based one-time password (TOTP) and phone verification code as the 2nd factor. Recovery codes are not supported but users can enroll multiple factors, with an upper limit of 10.\n\nHaving a 2nd factor for recovery frees the user of the burden of having to store their recovery codes somewhere. It also reduces the attack surface since multiple recovery codes are usually generated compared to just having 1 backup factor.\n\nLearn more about implementing MFA in your application [in the MFA guide](https://supabase.com/docs/guides/auth/auth-mfa#overview)." + }, + { + "id": "auth-mfa-challenge", + "$ref": "@supabase/auth-js.GoTrueMFAApi.challenge" + }, + { + "id": "auth-mfa-challengeandverify", + "$ref": "@supabase/auth-js.GoTrueMFAApi.challengeAndVerify" + }, + { + "id": "auth-mfa-enroll", + "$ref": "@supabase/auth-js.GoTrueMFAApi.enroll" + }, + { + "id": "auth-mfa-getauthenticatorassurancelevel", + "$ref": "@supabase/auth-js.GoTrueMFAApi.getAuthenticatorAssuranceLevel" + }, + { + "id": "auth-mfa-listfactors", + "$ref": "@supabase/auth-js.GoTrueMFAApi.listFactors" + }, + { + "id": "auth-mfa-unenroll", + "$ref": "@supabase/auth-js.GoTrueMFAApi.unenroll" + }, + { + "id": "auth-mfa-verify", + "$ref": "@supabase/auth-js.GoTrueMFAApi.verify" + }, + { + "id": "auth-passkey", + "title": "Auth Passkey", + "description": "This section contains methods for WebAuthn passkey registration, authentication, and management. Methods are invoked behind the `supabase.auth.passkey` namespace.\n\nPasskey support is an experimental feature. Enable it when creating the client:", + "code": "```js\nconst supabase = createClient(supabaseUrl, publishableKey, {\n auth: {\n experimental: { passkey: true },\n },\n})\n```" + }, + { + "id": "auth-passkey-delete", + "$ref": "@supabase/auth-js.AuthPasskeyApi.delete" + }, + { + "id": "auth-passkey-list", + "$ref": "@supabase/auth-js.AuthPasskeyApi.list" + }, + { + "id": "auth-passkey-startauthentication", + "$ref": "@supabase/auth-js.AuthPasskeyApi.startAuthentication" + }, + { + "id": "auth-passkey-startregistration", + "$ref": "@supabase/auth-js.AuthPasskeyApi.startRegistration" + }, + { + "id": "auth-passkey-update", + "$ref": "@supabase/auth-js.AuthPasskeyApi.update" + }, + { + "id": "auth-passkey-verifyauthentication", + "$ref": "@supabase/auth-js.AuthPasskeyApi.verifyAuthentication" + }, + { + "id": "auth-passkey-verifyregistration", + "$ref": "@supabase/auth-js.AuthPasskeyApi.verifyRegistration" + }, + { + "id": "oauth-admin", + "title": "OAuth Admin", + "description": "The OAuth Admin API allows you to manage OAuth clients programmatically. Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. These functions should only be called on a server. Never expose your `secret` key in the browser." + }, + { + "id": "oauth-admin-createclient", + "$ref": "@supabase/auth-js.GoTrueAdminOAuthApi.createClient" + }, + { + "id": "oauth-admin-deleteclient", + "$ref": "@supabase/auth-js.GoTrueAdminOAuthApi.deleteClient" + }, + { + "id": "oauth-admin-getclient", + "$ref": "@supabase/auth-js.GoTrueAdminOAuthApi.getClient" + }, + { + "id": "oauth-admin-listclients", + "$ref": "@supabase/auth-js.GoTrueAdminOAuthApi.listClients" + }, + { + "id": "oauth-admin-regenerateclientsecret", + "$ref": "@supabase/auth-js.GoTrueAdminOAuthApi.regenerateClientSecret" + }, + { + "id": "oauth-admin-updateclient", + "$ref": "@supabase/auth-js.GoTrueAdminOAuthApi.updateClient" + }, + { + "id": "oauth-server", + "title": "OAuth Server", + "description": "The OAuth Server API allows you to build custom OAuth consent screens for your application. Only relevant when the OAuth 2.1 server is enabled in Supabase Auth." + }, + { + "id": "oauth-server-approveauthorization", + "$ref": "@supabase/auth-js.AuthOAuthServerApi.approveAuthorization" + }, + { + "id": "oauth-server-denyauthorization", + "$ref": "@supabase/auth-js.AuthOAuthServerApi.denyAuthorization" + }, + { + "id": "oauth-server-getauthorizationdetails", + "$ref": "@supabase/auth-js.AuthOAuthServerApi.getAuthorizationDetails" + }, + { + "id": "oauth-server-listgrants", + "$ref": "@supabase/auth-js.AuthOAuthServerApi.listGrants" + }, + { + "id": "oauth-server-revokegrant", + "$ref": "@supabase/auth-js.AuthOAuthServerApi.revokeGrant" + }, + { + "id": "passkey-admin", + "title": "Passkey admin", + "description": "Contains passkey administration methods. Requires a secret key." + }, + { + "id": "passkey-admin-deletepasskey", + "$ref": "@supabase/auth-js.GoTrueAdminPasskeyApi.deletePasskey" + }, + { + "id": "passkey-admin-listpasskeys", + "$ref": "@supabase/auth-js.GoTrueAdminPasskeyApi.listPasskeys" + }, + { + "id": "functions-corsheaders", + "$ref": "@supabase/supabase-js.cors.corsHeaders" + }, + { + "id": "functions-invoke", + "$ref": "@supabase/functions-js.FunctionsClient.invoke" + }, + { + "id": "functions-setauth", + "$ref": "@supabase/functions-js.FunctionsClient.setAuth" + }, + { + "id": "channel", + "$ref": "@supabase/realtime-js.RealtimeClient.channel" + }, + { + "id": "connect", + "$ref": "@supabase/realtime-js.RealtimeClient.connect" + }, + { + "id": "connectionstate", + "$ref": "@supabase/realtime-js.RealtimeClient.connectionState" + }, + { + "id": "disconnect", + "$ref": "@supabase/realtime-js.RealtimeClient.disconnect" + }, + { + "id": "endpointurl", + "$ref": "@supabase/realtime-js.RealtimeClient.endpointURL" + }, + { + "id": "getchannels", + "$ref": "@supabase/realtime-js.RealtimeClient.getChannels" + }, + { + "id": "getwebsocketconstructor", + "$ref": "@supabase/realtime-js.WebSocketFactory.getWebSocketConstructor" + }, + { + "id": "httpsend", + "$ref": "@supabase/realtime-js.RealtimeChannel.httpSend" + }, + { + "id": "isconnected", + "$ref": "@supabase/realtime-js.RealtimeClient.isConnected" + }, + { + "id": "isconnecting", + "$ref": "@supabase/realtime-js.RealtimeClient.isConnecting" + }, + { + "id": "isdisconnecting", + "$ref": "@supabase/realtime-js.RealtimeClient.isDisconnecting" + }, + { + "id": "iswebsocketsupported", + "$ref": "@supabase/realtime-js.WebSocketFactory.isWebSocketSupported" + }, + { + "id": "log", + "$ref": "@supabase/realtime-js.RealtimeClient.log" + }, + { + "id": "on", + "$ref": "@supabase/realtime-js.RealtimeChannel.on" + }, + { + "id": "onheartbeat", + "$ref": "@supabase/realtime-js.RealtimeClient.onHeartbeat" + }, + { + "id": "presencestate", + "$ref": "@supabase/realtime-js.RealtimeChannel.presenceState" + }, + { + "id": "push", + "$ref": "@supabase/realtime-js.RealtimeClient.push" + }, + { + "id": "removeallchannels", + "$ref": "@supabase/realtime-js.RealtimeClient.removeAllChannels" + }, + { + "id": "removechannel", + "$ref": "@supabase/realtime-js.RealtimeClient.removeChannel" + }, + { + "id": "send", + "$ref": "@supabase/realtime-js.RealtimeChannel.send" + }, + { + "id": "sendheartbeat", + "$ref": "@supabase/realtime-js.RealtimeClient.sendHeartbeat" + }, + { + "id": "setauth", + "$ref": "@supabase/realtime-js.RealtimeClient.setAuth" + }, + { + "id": "subscribe", + "$ref": "@supabase/realtime-js.RealtimeChannel.subscribe" + }, + { + "id": "teardown", + "$ref": "@supabase/realtime-js.RealtimeChannel.teardown" + }, + { + "id": "track", + "$ref": "@supabase/realtime-js.RealtimeChannel.track" + }, + { + "id": "unsubscribe", + "$ref": "@supabase/realtime-js.RealtimeChannel.unsubscribe" + }, + { + "id": "untrack", + "$ref": "@supabase/realtime-js.RealtimeChannel.untrack" + }, + { + "id": "updatejoinpayload", + "$ref": "@supabase/realtime-js.RealtimeChannel.updateJoinPayload" + }, + { + "id": "analytics-buckets", + "title": "Analytics Buckets", + "description": "This section contains methods for working with Analytics Buckets." + }, + { + "id": "analytics-buckets-createbucket", + "$ref": "@supabase/storage-js.packages/StorageAnalyticsClient.default.createBucket" + }, + { + "id": "analytics-buckets-deletebucket", + "$ref": "@supabase/storage-js.packages/StorageAnalyticsClient.default.deleteBucket" + }, + { + "id": "analytics-buckets-from", + "$ref": "@supabase/storage-js.packages/StorageAnalyticsClient.default.from" + }, + { + "id": "analytics-buckets-listbuckets", + "$ref": "@supabase/storage-js.packages/StorageAnalyticsClient.default.listBuckets" + }, + { + "id": "file-buckets", + "title": "File Buckets", + "description": "This section contains methods for working with File Buckets." + }, + { + "id": "file-buckets-copy", + "$ref": "@supabase/storage-js.packages/StorageFileApi.default.copy" + }, + { + "id": "file-buckets-createbucket", + "$ref": "@supabase/storage-js.StorageClient.createBucket" + }, + { + "id": "file-buckets-createsigneduploadurl", + "$ref": "@supabase/storage-js.packages/StorageFileApi.default.createSignedUploadUrl" + }, + { + "id": "file-buckets-createsignedurl", + "$ref": "@supabase/storage-js.packages/StorageFileApi.default.createSignedUrl" + }, + { + "id": "file-buckets-createsignedurls", + "$ref": "@supabase/storage-js.packages/StorageFileApi.default.createSignedUrls" + }, + { + "id": "file-buckets-deletebucket", + "$ref": "@supabase/storage-js.StorageClient.deleteBucket" + }, + { + "id": "file-buckets-download", + "$ref": "@supabase/storage-js.packages/StorageFileApi.default.download" + }, + { + "id": "file-buckets-emptybucket", + "$ref": "@supabase/storage-js.StorageClient.emptyBucket" + }, + { + "id": "file-buckets-exists", + "$ref": "@supabase/storage-js.packages/StorageFileApi.default.exists" + }, + { + "id": "file-buckets-from", + "$ref": "@supabase/storage-js.StorageClient.from" + }, + { + "id": "file-buckets-getbucket", + "$ref": "@supabase/storage-js.StorageClient.getBucket" + }, + { + "id": "file-buckets-getpublicurl", + "$ref": "@supabase/storage-js.packages/StorageFileApi.default.getPublicUrl" + }, + { + "id": "file-buckets-info", + "$ref": "@supabase/storage-js.packages/StorageFileApi.default.info" + }, + { + "id": "file-buckets-list", + "$ref": "@supabase/storage-js.packages/StorageFileApi.default.list" + }, + { + "id": "file-buckets-listbuckets", + "$ref": "@supabase/storage-js.StorageClient.listBuckets" + }, + { + "id": "file-buckets-listv2", + "$ref": "@supabase/storage-js.packages/StorageFileApi.default.listV2" + }, + { + "id": "file-buckets-move", + "$ref": "@supabase/storage-js.packages/StorageFileApi.default.move" + }, + { + "id": "file-buckets-remove", + "$ref": "@supabase/storage-js.packages/StorageFileApi.default.remove" + }, + { + "id": "file-buckets-update", + "$ref": "@supabase/storage-js.packages/StorageFileApi.default.update" + }, + { + "id": "file-buckets-updatebucket", + "$ref": "@supabase/storage-js.StorageClient.updateBucket" + }, + { + "id": "file-buckets-upload", + "$ref": "@supabase/storage-js.packages/StorageFileApi.default.upload" + }, + { + "id": "file-buckets-uploadtosignedurl", + "$ref": "@supabase/storage-js.packages/StorageFileApi.default.uploadToSignedUrl" + }, + { + "id": "vector-buckets", + "title": "Vector Buckets", + "description": "This section contains methods for working with Vector Buckets." + }, + { + "id": "vector-buckets-createbucket", + "$ref": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.createBucket" + }, + { + "id": "vector-buckets-createindex", + "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.createIndex" + }, + { + "id": "vector-buckets-deletebucket", + "$ref": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.deleteBucket" + }, + { + "id": "vector-buckets-deleteindex", + "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.deleteIndex" + }, + { + "id": "vector-buckets-deletevectors", + "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.deleteVectors" + }, + { + "id": "vector-buckets-from", + "$ref": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.from" + }, + { + "id": "vector-buckets-getbucket", + "$ref": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.getBucket" + }, + { + "id": "vector-buckets-getindex", + "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.getIndex" + }, + { + "id": "vector-buckets-getvectors", + "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.getVectors" + }, + { + "id": "vector-buckets-index", + "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope" + }, + { + "id": "vector-buckets-listbuckets", + "$ref": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.listBuckets" + }, + { + "id": "vector-buckets-listindexes", + "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.listIndexes" + }, + { + "id": "vector-buckets-listvectors", + "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.listVectors" + }, + { + "id": "vector-buckets-putvectors", + "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.putVectors" + }, + { + "id": "vector-buckets-queryvectors", + "$ref": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.queryVectors" + } + ], + "typeSpec": { + "methods": { + "@supabase/functions-js.FunctionsClient.constructor": { + "name": "@supabase/functions-js.FunctionsClient.constructor", + "params": [ + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "type": { + "type": "object", + "properties": [ + { + "name": "customFetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RequestInfo" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true + }, + { + "name": "headers", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true + }, + { + "name": "region", + "type": { + "type": "nameOnly", + "name": "FunctionRegion" + }, + "isOptional": true + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "FunctionsClient" + } + }, + "comment": { + "shortText": "Creates a new Functions client bound to an Edge Functions URL.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst { data, error } = await supabase.functions.invoke('hello-world')\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport { FunctionsClient, FunctionRegion } from '@supabase/functions-js'\n\nconst functions = new FunctionsClient('https://xyzcompany.supabase.co/functions/v1', {\n headers: { apikey: 'your-publishable-key' },\n region: FunctionRegion.UsEast1,\n})\n```" + } + ] + } + }, + "@supabase/functions-js.FunctionsClient.invoke": { + "name": "@supabase/functions-js.FunctionsClient.invoke", + "params": [ + { + "name": "functionName", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The name of the Function to invoke." + } + }, + { + "name": "options", + "type": { + "name": "FunctionInvokeOptions", + "type": "object", + "properties": [ + { + "name": "body", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "File" + }, + { + "type": "nameOnly", + "name": "Blob" + }, + { + "type": "nameOnly", + "name": "ArrayBuffer" + }, + { + "type": "nameOnly", + "name": "FormData" + }, + { + "type": "nameOnly", + "name": "ReadableStream" + }, + { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The body of the request." + } + }, + { + "name": "headers", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Object representing the headers to send with the request." + } + }, + { + "name": "method", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "POST" + }, + { + "type": "literal", + "value": "GET" + }, + { + "type": "literal", + "value": "PUT" + }, + { + "type": "literal", + "value": "PATCH" + }, + { + "type": "literal", + "value": "DELETE" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The HTTP verb of the request" + } + }, + { + "name": "region", + "type": { + "type": "nameOnly", + "name": "FunctionRegion" + }, + "isOptional": true, + "comment": { + "shortText": "The Region to invoke the function in." + } + }, + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "isOptional": true, + "comment": { + "shortText": "The AbortSignal to use for the request." + } + }, + { + "name": "timeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "The timeout for the request in milliseconds.\nIf the function takes longer than this, the request will be aborted." + } + } + ] + }, + "comment": { + "shortText": "Options for invoking the Function." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "FunctionsResponse", + "subTypes": [ + { + "type": "nameOnly", + "name": "FunctionsResponseSuccess" + }, + { + "type": "nameOnly", + "name": "FunctionsResponseFailure" + } + ] + } + } + }, + "comment": { + "shortText": "Invokes a function", + "text": "- Requires an Authorization header.\n- Invoke params generally match the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) spec.\n- When you pass in a body to your function, we automatically attach the Content-Type header for `Blob`, `ArrayBuffer`, `File`, `FormData` and `String`. If it doesn't match any of these types we assume the payload is `json`, serialize it and attach the `Content-Type` header as `application/json`. You can override this behavior by passing in a `Content-Type` header of your own.\n- Responses are automatically parsed as `json`, `blob` and `form-data` depending on the `Content-Type` header sent by your function. Responses are parsed as `text` by default.", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\nconst { data, error } = await functions.invoke('hello-world', {\n body: { name: 'Ada' },\n})\n```" + }, + { + "id": "basic-invocation", + "name": "Basic invocation", + "code": "```js\nconst { data, error } = await supabase.functions.invoke('hello', {\n body: { foo: 'bar' }\n})\n```" + }, + { + "id": "error-handling", + "name": "Error handling", + "code": "```js\nimport { FunctionsHttpError, FunctionsRelayError, FunctionsFetchError } from \"@supabase/supabase-js\";\n\nconst { data, error } = await supabase.functions.invoke('hello', {\n headers: {\n \"my-custom-header\": 'my-custom-header-value'\n },\n body: { foo: 'bar' }\n})\n\nif (error instanceof FunctionsHttpError) {\n const errorMessage = await error.context.json()\n console.error('Function returned an error', errorMessage)\n} else if (error instanceof FunctionsRelayError) {\n console.error('Relay error:', error)\n} else if (error instanceof FunctionsFetchError) {\n console.error('Fetch error:', error)\n}\n```", + "description": "A `FunctionsHttpError` error is returned if your function throws an error, `FunctionsRelayError` if the Supabase Relay has an error processing your function and `FunctionsFetchError` if there is a network error in calling your function. Log the full error object so fields like `name`, `context`, and any structured body aren't hidden." + }, + { + "id": "passing-custom-headers", + "name": "Passing custom headers", + "code": "```js\nconst { data, error } = await supabase.functions.invoke('hello', {\n headers: {\n \"my-custom-header\": 'my-custom-header-value'\n },\n body: { foo: 'bar' }\n})\n```", + "description": "You can pass custom headers to your function. Note: supabase-js automatically passes the `Authorization` header with the signed in user's JWT." + }, + { + "id": "calling-with-delete-http-verb", + "name": "Calling with DELETE HTTP verb", + "code": "```js\nconst { data, error } = await supabase.functions.invoke('hello', {\n headers: {\n \"my-custom-header\": 'my-custom-header-value'\n },\n body: { foo: 'bar' },\n method: 'DELETE'\n})\n```", + "description": "You can also set the HTTP verb to `DELETE` when calling your Edge Function." + }, + { + "id": "invoking-a-function-in-the-useast1-region", + "name": "Invoking a Function in the UsEast1 region", + "code": "```js\nimport { createClient, FunctionRegion } from '@supabase/supabase-js'\n\nconst { data, error } = await supabase.functions.invoke('hello', {\n body: { foo: 'bar' },\n region: FunctionRegion.UsEast1\n})\n```", + "description": "Here are the available regions:\n- `FunctionRegion.Any`\n- `FunctionRegion.ApNortheast1`\n- `FunctionRegion.ApNortheast2`\n- `FunctionRegion.ApSouth1`\n- `FunctionRegion.ApSoutheast1`\n- `FunctionRegion.ApSoutheast2`\n- `FunctionRegion.CaCentral1`\n- `FunctionRegion.EuCentral1`\n- `FunctionRegion.EuWest1`\n- `FunctionRegion.EuWest2`\n- `FunctionRegion.EuWest3`\n- `FunctionRegion.SaEast1`\n- `FunctionRegion.UsEast1`\n- `FunctionRegion.UsWest1`\n- `FunctionRegion.UsWest2`" + }, + { + "id": "calling-with-get-http-verb", + "name": "Calling with GET HTTP verb", + "code": "```js\nconst { data, error } = await supabase.functions.invoke('hello', {\n headers: {\n \"my-custom-header\": 'my-custom-header-value'\n },\n method: 'GET'\n})\n```", + "description": "You can also set the HTTP verb to `GET` when calling your Edge Function." + }, + { + "id": "standalone-client-invoke", + "name": "Standalone client invoke", + "code": "```ts\nconst { data, error } = await functions.invoke('hello-world', {\n body: { name: 'Ada' },\n})\n```" + } + ] + } + }, + "@supabase/functions-js.FunctionsClient.setAuth": { + "name": "@supabase/functions-js.FunctionsClient.setAuth", + "params": [ + { + "name": "token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "the new jwt token sent in the authorisation header" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Updates the authorization header", + "examples": [ + { + "id": "setting-the-authorization-header", + "name": "Setting the authorization header", + "code": "```ts\nfunctions.setAuth(session.access_token)\n```" + } + ] + } + }, + "@supabase/functions-js.FunctionsError.constructor": { + "name": "@supabase/functions-js.FunctionsError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "context", + "type": { + "type": "intrinsic", + "name": "any" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "FunctionsError" + } + } + }, + "@supabase/functions-js.FunctionsError.toJSON": { + "name": "@supabase/functions-js.FunctionsError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "context", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + }, + "@supabase/functions-js.FunctionsFetchError.constructor": { + "name": "@supabase/functions-js.FunctionsFetchError.constructor", + "params": [ + { + "name": "context", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "FunctionsFetchError" + } + } + }, + "@supabase/functions-js.FunctionsFetchError.toJSON": { + "name": "@supabase/functions-js.FunctionsFetchError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "context", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + }, + "@supabase/functions-js.FunctionsHttpError.constructor": { + "name": "@supabase/functions-js.FunctionsHttpError.constructor", + "params": [ + { + "name": "context", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "FunctionsHttpError" + } + } + }, + "@supabase/functions-js.FunctionsHttpError.toJSON": { + "name": "@supabase/functions-js.FunctionsHttpError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "context", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + }, + "@supabase/functions-js.FunctionsRelayError.constructor": { + "name": "@supabase/functions-js.FunctionsRelayError.constructor", + "params": [ + { + "name": "context", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "FunctionsRelayError" + } + } + }, + "@supabase/functions-js.FunctionsRelayError.toJSON": { + "name": "@supabase/functions-js.FunctionsRelayError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "context", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + }, + "@supabase/auth-js.AuthApiError.constructor": { + "name": "@supabase/auth-js.AuthApiError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthApiError" + } + } + }, + "@supabase/auth-js.AuthApiError.toJSON": { + "name": "@supabase/auth-js.AuthApiError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + null, + { + "type": "nameOnly", + "name": "ErrorCode" + } + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/auth-js.AuthError.constructor": { + "name": "@supabase/auth-js.AuthError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + }, + "@supabase/auth-js.AuthError.toJSON": { + "name": "@supabase/auth-js.AuthError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + null, + { + "type": "nameOnly", + "name": "ErrorCode" + } + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/auth-js.AuthImplicitGrantRedirectError.constructor": { + "name": "@supabase/auth-js.AuthImplicitGrantRedirectError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "details", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthImplicitGrantRedirectError" + } + } + }, + "@supabase/auth-js.AuthImplicitGrantRedirectError.toJSON": { + "name": "@supabase/auth-js.AuthImplicitGrantRedirectError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + null, + { + "type": "nameOnly", + "name": "ErrorCode" + } + ] + } + }, + { + "name": "details", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/auth-js.AuthInvalidCredentialsError.constructor": { + "name": "@supabase/auth-js.AuthInvalidCredentialsError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthInvalidCredentialsError" + } + } + }, + "@supabase/auth-js.AuthInvalidCredentialsError.toJSON": { + "name": "@supabase/auth-js.AuthInvalidCredentialsError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + null, + { + "type": "nameOnly", + "name": "ErrorCode" + } + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/auth-js.AuthInvalidJwtError.constructor": { + "name": "@supabase/auth-js.AuthInvalidJwtError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthInvalidJwtError" + } + } + }, + "@supabase/auth-js.AuthInvalidJwtError.toJSON": { + "name": "@supabase/auth-js.AuthInvalidJwtError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + null, + { + "type": "nameOnly", + "name": "ErrorCode" + } + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/auth-js.AuthInvalidTokenResponseError.constructor": { + "name": "@supabase/auth-js.AuthInvalidTokenResponseError.constructor", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthInvalidTokenResponseError" + } + } + }, + "@supabase/auth-js.AuthInvalidTokenResponseError.toJSON": { + "name": "@supabase/auth-js.AuthInvalidTokenResponseError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + null, + { + "type": "nameOnly", + "name": "ErrorCode" + } + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/auth-js.AuthPKCECodeVerifierMissingError.constructor": { + "name": "@supabase/auth-js.AuthPKCECodeVerifierMissingError.constructor", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthPKCECodeVerifierMissingError" + } + } + }, + "@supabase/auth-js.AuthPKCECodeVerifierMissingError.toJSON": { + "name": "@supabase/auth-js.AuthPKCECodeVerifierMissingError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + null, + { + "type": "nameOnly", + "name": "ErrorCode" + } + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/auth-js.AuthPKCEGrantCodeExchangeError.constructor": { + "name": "@supabase/auth-js.AuthPKCEGrantCodeExchangeError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "details", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthPKCEGrantCodeExchangeError" + } + } + }, + "@supabase/auth-js.AuthPKCEGrantCodeExchangeError.toJSON": { + "name": "@supabase/auth-js.AuthPKCEGrantCodeExchangeError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + null, + { + "type": "nameOnly", + "name": "ErrorCode" + } + ] + } + }, + { + "name": "details", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/auth-js.AuthRefreshDiscardedError.constructor": { + "name": "@supabase/auth-js.AuthRefreshDiscardedError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthRefreshDiscardedError" + } + } + }, + "@supabase/auth-js.AuthRefreshDiscardedError.toJSON": { + "name": "@supabase/auth-js.AuthRefreshDiscardedError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + null, + { + "type": "nameOnly", + "name": "ErrorCode" + } + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/auth-js.AuthRetryableFetchError.constructor": { + "name": "@supabase/auth-js.AuthRetryableFetchError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthRetryableFetchError" + } + } + }, + "@supabase/auth-js.AuthRetryableFetchError.toJSON": { + "name": "@supabase/auth-js.AuthRetryableFetchError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + null, + { + "type": "nameOnly", + "name": "ErrorCode" + } + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/auth-js.AuthSessionMissingError.constructor": { + "name": "@supabase/auth-js.AuthSessionMissingError.constructor", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthSessionMissingError" + } + } + }, + "@supabase/auth-js.AuthSessionMissingError.toJSON": { + "name": "@supabase/auth-js.AuthSessionMissingError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + null, + { + "type": "nameOnly", + "name": "ErrorCode" + } + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/auth-js.AuthUnknownError.constructor": { + "name": "@supabase/auth-js.AuthUnknownError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "originalError", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthUnknownError" + } + } + }, + "@supabase/auth-js.AuthUnknownError.toJSON": { + "name": "@supabase/auth-js.AuthUnknownError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + null, + { + "type": "nameOnly", + "name": "ErrorCode" + } + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/auth-js.AuthWeakPasswordError.constructor": { + "name": "@supabase/auth-js.AuthWeakPasswordError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "reasons", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "length" + }, + { + "type": "literal", + "value": "characters" + }, + { + "type": "literal", + "value": "pwned" + } + ] + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthWeakPasswordError" + } + } + }, + "@supabase/auth-js.AuthWeakPasswordError.toJSON": { + "name": "@supabase/auth-js.AuthWeakPasswordError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + null, + { + "type": "nameOnly", + "name": "ErrorCode" + } + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "reasons", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "length" + }, + { + "type": "literal", + "value": "characters" + }, + { + "type": "literal", + "value": "pwned" + } + ] + } + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/auth-js.CustomAuthError.constructor": { + "name": "@supabase/auth-js.CustomAuthError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "CustomAuthError" + } + } + }, + "@supabase/auth-js.CustomAuthError.toJSON": { + "name": "@supabase/auth-js.CustomAuthError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + null, + { + "type": "nameOnly", + "name": "ErrorCode" + } + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/auth-js.GoTrueAdminApi.constructor": { + "name": "@supabase/auth-js.GoTrueAdminApi.constructor", + "params": [ + { + "type": { + "type": "object", + "properties": [ + { + "name": "experimental", + "type": { + "name": "ExperimentalFeatureFlags", + "type": "object", + "properties": [ + { + "name": "passkey", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Enables passkey support:\n - `auth.signInWithPasskey()`, `auth.registerPasskey()`\n - `auth.passkey.*`\n - `auth.admin.passkey.*`\n\nDefaults to `false`. Calling any passkey method while this flag is\ndisabled throws a descriptive error at call time." + } + } + ] + }, + "isOptional": true + }, + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "URL" + }, + { + "type": "nameOnly", + "name": "RequestInfo" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true + }, + { + "name": "headers", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true + }, + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "GoTrueAdminApi" + } + }, + "comment": { + "shortText": "Creates an admin API client that can be used to manage users and OAuth clients.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-secret-key')\nconst { data, error } = await supabase.auth.admin.listUsers()\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport { GoTrueAdminApi } from '@supabase/auth-js'\n\nconst admin = new GoTrueAdminApi({\n url: 'https://xyzcompany.supabase.co/auth/v1',\n headers: { Authorization: `Bearer ${process.env.SUPABASE_SECRET_KEY}` },\n})\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueAdminApi.createUser": { + "name": "@supabase/auth-js.GoTrueAdminApi.createUser", + "params": [ + { + "name": "attributes", + "type": { + "type": "object", + "name": "AdminUserAttributes", + "properties": [ + { + "name": "app_metadata", + "type": { + "type": "intrinsic", + "name": "object" + }, + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's application specific metadata. This maps to the `auth.users.app_metadata` column.\n\nOnly a service role can modify.\n\nThe `app_metadata` should be a JSON object that includes app-specific info, such as identity providers, roles, and other\naccess control information." + } + }, + { + "name": "ban_duration", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Determines how long a user is banned for.\n\nThe format for the ban duration follows a strict sequence of decimal numbers with a unit suffix.\nValid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\".\n\nFor example, some possible durations include: '300ms', '2h45m'.\n\nSetting the ban duration to 'none' lifts the ban on the user." + } + }, + { + "name": "current_password", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The user's current password\n\nThis is only ever present when the user is resetting\ntheir password and GOTRUE_SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD is true." + } + }, + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The user's email." + } + }, + { + "name": "email_confirm", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Sets the user's email as confirmed when true, or unconfirmed when false.\n\nOnly a service role can modify." + } + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The `id` for the user.\n\nAllows you to overwrite the default `id` set for the user." + } + }, + { + "name": "nonce", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The nonce sent for reauthentication if the user's password is to be updated.\n\nCall reauthenticate() to obtain the nonce first." + } + }, + { + "name": "password", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The user's password." + } + }, + { + "name": "password_hash", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The `password_hash` for the user's password.\n\nAllows you to specify a password hash for the user. This is useful for migrating a user's password hash from another service.\n\nSupports bcrypt, scrypt (firebase), and argon2 password hashes." + } + }, + { + "name": "phone", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The user's phone." + } + }, + { + "name": "phone_confirm", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Sets the user's phone as confirmed when true, or unconfirmed when false.\n\nOnly a service role can modify." + } + }, + { + "name": "role", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The `role` claim set in the user's access token JWT.\n\nWhen a user signs up, this role is set to `authenticated` by default. You should only modify the `role` if you need to provision several levels of admin access that have different permissions on individual columns in your database.\n\nSetting this role to `service_role` is not recommended as it grants the user admin privileges." + } + }, + { + "name": "user_metadata", + "type": { + "type": "intrinsic", + "name": "object" + }, + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.\n\n\nThe `user_metadata` should be a JSON object that includes user-specific info, such as their first and last name.\n\nNote: When using the GoTrueAdminApi and wanting to modify a user's metadata,\nthis attribute is used instead of UserAttributes data." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "UserResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "banned_until", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "confirmed_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "deleted_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "totp" + }, + { + "type": "literal", + "value": "phone" + }, + { + "type": "literal", + "value": "webauthn" + } + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "totp" + }, + { + "type": "literal", + "value": "phone" + }, + { + "type": "literal", + "value": "webauthn" + } + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "last_sign_in_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "provider", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "updated_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "user_id", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "is_anonymous", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "is_sso_user", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "new_email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "new_phone", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "phone", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "role", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "updated_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "literal", + "value": null + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a new user.\nThis function should only be called on a server. Never expose your `service_role` key in the browser.", + "text": "- To confirm the user's email address or phone number, set `email_confirm` or `phone_confirm` to true. Both arguments default to false.\n- `createUser()` will not send a confirmation email to the user. You can use [`inviteUserByEmail()`](/docs/reference/javascript/auth-admin-inviteuserbyemail) if you want to send them an email invite instead.\n- If you are sure that the created user's email or phone number is legitimate and verified, you can set the `email_confirm` or `phone_confirm` param to `true`.", + "examples": [ + { + "id": "with-custom-user-metadata", + "name": "With custom user metadata", + "code": "```js\nconst { data, error } = await supabase.auth.admin.createUser({\n email: 'user@email.com',\n password: 'password',\n user_metadata: { name: 'Yoda' }\n})\n```", + "response": "```json\n{\n data: {\n user: {\n id: '1',\n aud: 'authenticated',\n role: 'authenticated',\n email: 'example@email.com',\n email_confirmed_at: '2024-01-01T00:00:00Z',\n phone: '',\n confirmation_sent_at: '2024-01-01T00:00:00Z',\n confirmed_at: '2024-01-01T00:00:00Z',\n last_sign_in_at: '2024-01-01T00:00:00Z',\n app_metadata: {},\n user_metadata: {},\n identities: [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"1\",\n \"user_id\": \"1\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": true,\n \"phone_verified\": false,\n \"sub\": \"1\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"email@example.com\"\n },\n ],\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n is_anonymous: false,\n }\n }\n error: null\n}\n```" + }, + { + "id": "auto-confirm-the-user-s-email", + "name": "Auto-confirm the user's email", + "code": "```js\nconst { data, error } = await supabase.auth.admin.createUser({\n email: 'user@email.com',\n email_confirm: true\n})\n```" + }, + { + "id": "auto-confirm-the-user-s-phone-number", + "name": "Auto-confirm the user's phone number", + "code": "```js\nconst { data, error } = await supabase.auth.admin.createUser({\n phone: '1234567890',\n phone_confirm: true\n})\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueAdminApi.deleteUser": { + "name": "@supabase/auth-js.GoTrueAdminApi.deleteUser", + "params": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user id you want to remove." + } + }, + { + "name": "shouldSoftDelete", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "comment": { + "shortText": "If true, then the user will be soft-deleted from the auth schema. Soft deletion allows user identification from the hashed user ID but is not reversible.\nDefaults to false for backward compatibility.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "UserResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Delete a user. Requires a `service_role` key.", + "text": "- The `deleteUser()` method requires the user's ID, which maps to the `auth.users.id` column.", + "examples": [ + { + "id": "removes-a-user", + "name": "Removes a user", + "code": "```js\nconst { data, error } = await supabase.auth.admin.deleteUser(\n '715ed5db-f090-4b8c-a067-640ecee36aa0'\n)\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {}\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueAdminApi.generateLink": { + "name": "@supabase/auth-js.GoTrueAdminApi.generateLink", + "params": [ + { + "name": "params", + "type": { + "type": "union", + "name": "GenerateLinkParams", + "subTypes": [ + { + "name": "GenerateSignupLinkParams", + "type": "object", + "properties": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "isOptional": true + }, + { + "name": "password", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "signup" + } + } + ] + }, + { + "name": "GenerateInviteOrMagiclinkParams", + "type": "object", + "properties": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's email" + } + }, + { + "name": "options", + "isOptional": true + }, + { + "name": "type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "invite" + }, + { + "type": "literal", + "value": "magiclink" + } + ] + } + } + ] + }, + { + "name": "GenerateRecoveryLinkParams", + "type": "object", + "properties": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's email" + } + }, + { + "name": "options", + "isOptional": true + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "recovery" + } + } + ] + }, + { + "name": "GenerateEmailChangeLinkParams", + "type": "object", + "properties": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's email" + } + }, + { + "name": "newEmail", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's new email. Only required if type is 'email_change_current' or 'email_change_new'." + } + }, + { + "name": "options", + "isOptional": true + }, + { + "name": "type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "email_change_current" + }, + { + "type": "literal", + "value": "email_change_new" + } + ] + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "GenerateLinkResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "properties", + "type": { + "name": "GenerateLinkProperties", + "type": "object", + "properties": [ + { + "name": "action_link", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The email link to send to the user.\nThe action_link follows the following format: auth/v1/verify?type={verification_type}&token={hashed_token}&redirect_to={redirect_to}" + } + }, + { + "name": "email_otp", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The raw email OTP.\nYou should send this in the email if you want your users to verify using an OTP instead of the action link." + } + }, + { + "name": "hashed_token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The hashed token appended to the action link." + } + }, + { + "name": "redirect_to", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The URL appended to the action link." + } + }, + { + "name": "verification_type", + "type": { + "type": "union", + "name": "GenerateLinkType", + "subTypes": [ + { + "type": "literal", + "value": "signup" + }, + { + "type": "literal", + "value": "invite" + }, + { + "type": "literal", + "value": "magiclink" + }, + { + "type": "literal", + "value": "recovery" + }, + { + "type": "literal", + "value": "email_change_current" + }, + { + "type": "literal", + "value": "email_change_new" + } + ] + }, + "comment": { + "shortText": "The verification type that the email link is associated to." + } + } + ] + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "properties", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Generates email links and OTPs to be sent via a custom email provider.", + "text": "- The following types can be passed into `generateLink()`: `signup`, `magiclink`, `invite`, `recovery`, `email_change_current`, `email_change_new`, `phone_change`.\n- `generateLink()` only generates the email link for `email_change_email` if the **Secure email change** is enabled in your project's [email auth provider settings](/dashboard/project/_/auth/providers).\n- `generateLink()` handles the creation of the user for `signup`, `invite` and `magiclink`.", + "examples": [ + { + "id": "generate-a-signup-link", + "name": "Generate a signup link", + "code": "```js\nconst { data, error } = await supabase.auth.admin.generateLink({\n type: 'signup',\n email: 'email@example.com',\n password: 'secret'\n})\n```", + "response": "```json\n{\n \"data\": {\n \"properties\": {\n \"action_link\": \"\",\n \"email_otp\": \"999999\",\n \"hashed_token\": \"\",\n \"verification_type\": \"signup\"\n },\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"email@example.com\",\n \"phone\": \"\",\n \"confirmation_sent_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {},\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"email@example.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"email@example.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "generate-an-invite-link", + "name": "Generate an invite link", + "code": "```js\nconst { data, error } = await supabase.auth.admin.generateLink({\n type: 'invite',\n email: 'email@example.com'\n})\n```" + }, + { + "id": "generate-a-magic-link", + "name": "Generate a magic link", + "code": "```js\nconst { data, error } = await supabase.auth.admin.generateLink({\n type: 'magiclink',\n email: 'email@example.com'\n})\n```" + }, + { + "id": "generate-a-recovery-link", + "name": "Generate a recovery link", + "code": "```js\nconst { data, error } = await supabase.auth.admin.generateLink({\n type: 'recovery',\n email: 'email@example.com'\n})\n```" + }, + { + "id": "generate-links-to-change-current-email-address", + "name": "Generate links to change current email address", + "code": "```js\n// generate an email change link to be sent to the current email address\nconst { data, error } = await supabase.auth.admin.generateLink({\n type: 'email_change_current',\n email: 'current.email@example.com',\n newEmail: 'new.email@example.com'\n})\n\n// generate an email change link to be sent to the new email address\nconst { data, error } = await supabase.auth.admin.generateLink({\n type: 'email_change_new',\n email: 'current.email@example.com',\n newEmail: 'new.email@example.com'\n})\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueAdminApi.getUserById": { + "name": "@supabase/auth-js.GoTrueAdminApi.getUserById", + "params": [ + { + "name": "uid", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's unique identifier\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "UserResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Get user by id.", + "text": "- Fetches the user object from the database based on the user's id.\n- The `getUserById()` method requires the user's id which maps to the `auth.users.id` column.", + "examples": [ + { + "id": "fetch-the-user-object-using-the-access-token-jwt", + "name": "Fetch the user object using the access_token jwt", + "code": "```js\nconst { data, error } = await supabase.auth.admin.getUserById(1)\n```", + "response": "```json\n{\n data: {\n user: {\n id: '1',\n aud: 'authenticated',\n role: 'authenticated',\n email: 'example@email.com',\n email_confirmed_at: '2024-01-01T00:00:00Z',\n phone: '',\n confirmation_sent_at: '2024-01-01T00:00:00Z',\n confirmed_at: '2024-01-01T00:00:00Z',\n last_sign_in_at: '2024-01-01T00:00:00Z',\n app_metadata: {},\n user_metadata: {},\n identities: [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"1\",\n \"user_id\": \"1\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": true,\n \"phone_verified\": false,\n \"sub\": \"1\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"email@example.com\"\n },\n ],\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n is_anonymous: false,\n }\n }\n error: null\n}\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueAdminApi.inviteUserByEmail": { + "name": "@supabase/auth-js.GoTrueAdminApi.inviteUserByEmail", + "params": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The email address of the user." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "object" + }, + "isOptional": true, + "comment": { + "shortText": "A custom data object to store additional metadata about the user. This maps to the `auth.users.user_metadata` column." + } + }, + { + "name": "redirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The URL which will be appended to the email link sent to the user's email address. Once clicked the user will end up on this URL." + } + } + ] + }, + "comment": { + "shortText": "Additional options to be included when inviting." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "UserResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Sends an invite link to an email address.", + "text": "- Sends an invite link to the user's email address.\n- The `inviteUserByEmail()` method is typically used by administrators to invite users to join the application.\n- Note that PKCE is not supported when using `inviteUserByEmail`. This is because the browser initiating the invite is often different from the browser accepting the invite which makes it difficult to provide the security guarantees required of the PKCE flow.", + "examples": [ + { + "id": "invite-a-user", + "name": "Invite a user", + "code": "```js\nconst { data, error } = await supabase.auth.admin.inviteUserByEmail('email@example.com')\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"invited_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmation_sent_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {},\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n }\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueAdminApi.listUsers": { + "name": "@supabase/auth-js.GoTrueAdminApi.listUsers", + "params": [ + { + "name": "params", + "type": { + "name": "PageParams", + "type": "object", + "properties": [ + { + "name": "page", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "The page number" + } + }, + { + "name": "perPage", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "Number of items returned per page" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "An object which supports `page` and `perPage` as numbers, to alter the paginated results." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "users" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Get a list of users.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser.", + "text": "- Defaults to return 50 users per page.", + "examples": [ + { + "id": "get-a-page-of-users", + "name": "Get a page of users", + "code": "```js\nconst { data: { users }, error } = await supabase.auth.admin.listUsers()\n```" + }, + { + "id": "paginated-list-of-users", + "name": "Paginated list of users", + "code": "```js\nconst { data: { users }, error } = await supabase.auth.admin.listUsers({\n page: 1,\n perPage: 1000\n})\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueAdminApi.signOut": { + "name": "@supabase/auth-js.GoTrueAdminApi.signOut", + "params": [ + { + "name": "jwt", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "A valid, logged-in JWT." + } + }, + { + "name": "scope", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "global" + }, + { + "type": "literal", + "value": "local" + }, + { + "type": "literal", + "value": "others" + } + ] + }, + "comment": { + "shortText": "The logout sope." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "nameOnly", + "name": "AuthError" + } + ] + } + } + ] + } + } + }, + "comment": { + "shortText": "Removes a logged-in session." + } + }, + "@supabase/auth-js.GoTrueAdminApi.updateUserById": { + "name": "@supabase/auth-js.GoTrueAdminApi.updateUserById", + "params": [ + { + "name": "uid", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's unique identifier" + } + }, + { + "name": "attributes", + "type": { + "type": "object", + "name": "AdminUserAttributes", + "properties": [ + { + "name": "app_metadata", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's application specific metadata. This maps to the `auth.users.app_metadata` column.\n\nOnly a service role can modify.\n\nThe `app_metadata` should be a JSON object that includes app-specific info, such as identity providers, roles, and other\naccess control information." + } + }, + { + "name": "ban_duration", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Determines how long a user is banned for.\n\nThe format for the ban duration follows a strict sequence of decimal numbers with a unit suffix.\nValid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\".\n\nFor example, some possible durations include: '300ms', '2h45m'.\n\nSetting the ban duration to 'none' lifts the ban on the user." + } + }, + { + "name": "current_password", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The user's current password\n\nThis is only ever present when the user is resetting\ntheir password and GOTRUE_SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD is true." + } + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The user's email." + } + }, + { + "name": "email_confirm", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Sets the user's email as confirmed when true, or unconfirmed when false.\n\nOnly a service role can modify." + } + }, + { + "name": "id", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The `id` for the user.\n\nAllows you to overwrite the default `id` set for the user." + } + }, + { + "name": "nonce", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The nonce sent for reauthentication if the user's password is to be updated.\n\nCall reauthenticate() to obtain the nonce first." + } + }, + { + "name": "password", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The user's password." + } + }, + { + "name": "password_hash", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The `password_hash` for the user's password.\n\nAllows you to specify a password hash for the user. This is useful for migrating a user's password hash from another service.\n\nSupports bcrypt, scrypt (firebase), and argon2 password hashes." + } + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The user's phone." + } + }, + { + "name": "phone_confirm", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Sets the user's phone as confirmed when true, or unconfirmed when false.\n\nOnly a service role can modify." + } + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The `role` claim set in the user's access token JWT.\n\nWhen a user signs up, this role is set to `authenticated` by default. You should only modify the `role` if you need to provision several levels of admin access that have different permissions on individual columns in your database.\n\nSetting this role to `service_role` is not recommended as it grants the user admin privileges." + } + }, + { + "name": "user_metadata", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.\n\n\nThe `user_metadata` should be a JSON object that includes user-specific info, such as their first and last name.\n\nNote: When using the GoTrueAdminApi and wanting to modify a user's metadata,\nthis attribute is used instead of UserAttributes data." + } + } + ] + }, + "comment": { + "shortText": "The data you want to update.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "UserResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Updates the user data. Changes are applied directly without confirmation flows.", + "text": "**Important:** This is a server-side operation and does **not** trigger client-side\n`onAuthStateChange` listeners. The admin API has no connection to client state.\n\nTo sync changes to the client after calling this method:\n1. On the client, call `supabase.auth.refreshSession()` to fetch the updated user data\n2. This will trigger the `TOKEN_REFRESHED` event and notify all listeners", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```typescript\n// Server-side (Edge Function)\nconst { data, error } = await supabase.auth.admin.updateUserById(\n userId,\n { user_metadata: { preferences: { theme: 'dark' } } }\n)\n\n// Client-side (to sync the changes)\nconst { data, error } = await supabase.auth.refreshSession()\n// onAuthStateChange listeners will now be notified with updated user\n```" + }, + { + "id": "updates-a-user-s-email", + "name": "Updates a user's email", + "code": "```js\nconst { data: user, error } = await supabase.auth.admin.updateUserById(\n '11111111-1111-1111-1111-111111111111',\n { email: 'new@email.com' }\n)\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"new@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"recovery_sent_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "updates-a-user-s-password", + "name": "Updates a user's password", + "code": "```js\nconst { data: user, error } = await supabase.auth.admin.updateUserById(\n '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4',\n { password: 'new_password' }\n)\n```" + }, + { + "id": "updates-a-user-s-metadata", + "name": "Updates a user's metadata", + "code": "```js\nconst { data: user, error } = await supabase.auth.admin.updateUserById(\n '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4',\n { user_metadata: { hello: 'world' } }\n)\n```" + }, + { + "id": "updates-a-user-s-app-metadata", + "name": "Updates a user's app_metadata", + "code": "```js\nconst { data: user, error } = await supabase.auth.admin.updateUserById(\n '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4',\n { app_metadata: { plan: 'trial' } }\n)\n```" + }, + { + "id": "confirms-a-user-s-email-address", + "name": "Confirms a user's email address", + "code": "```js\nconst { data: user, error } = await supabase.auth.admin.updateUserById(\n '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4',\n { email_confirm: true }\n)\n```" + }, + { + "id": "confirms-a-user-s-phone-number", + "name": "Confirms a user's phone number", + "code": "```js\nconst { data: user, error } = await supabase.auth.admin.updateUserById(\n '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4',\n { phone_confirm: true }\n)\n```" + }, + { + "id": "ban-a-user-for-100-years", + "name": "Ban a user for 100 years", + "code": "```js\nconst { data: user, error } = await supabase.auth.admin.updateUserById(\n '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4',\n { ban_duration: '876000h' }\n)\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.constructor": { + "name": "@supabase/auth-js.GoTrueClient.constructor", + "params": [ + { + "name": "options", + "type": { + "name": "GoTrueClientOptions", + "type": "object", + "properties": [ + { + "name": "autoRefreshToken", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "debug", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "boolean" + }, + { + "type": "function", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "args", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "any" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + ] + }, + "isOptional": true + }, + { + "name": "detectSessionInUrl", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "boolean" + }, + { + "type": "function", + "params": [ + { + "name": "url", + "type": { + "type": "nameOnly", + "name": "URL" + } + }, + { + "name": "params", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "boolean" + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Set to \"true\" if you want to automatically detect OAuth grants in the URL and sign in the user.\nSet to \"false\" to disable automatic detection.\nSet to a function to provide custom logic for determining if a URL contains a Supabase auth callback.\nThe function receives the current URL and parsed parameters, and should return true if the URL\nshould be processed as a Supabase auth callback, or false to ignore it.\n\nThis is useful when your app uses other OAuth providers (e.g., Facebook Login) that also return\naccess_token in the URL fragment, which would otherwise be incorrectly intercepted by Supabase Auth.", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\ndetectSessionInUrl: (url, params) => {\n // Ignore Facebook OAuth redirects\n if (url.pathname === '/facebook/redirect') return false\n // Use default detection for other URLs\n return Boolean(params.access_token || params.error_description)\n}\n```" + } + ] + } + }, + { + "name": "experimental", + "type": { + "name": "ExperimentalFeatureFlags", + "type": "object", + "properties": [ + { + "name": "passkey", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Enables passkey support:\n - `auth.signInWithPasskey()`, `auth.registerPasskey()`\n - `auth.passkey.*`\n - `auth.admin.passkey.*`\n\nDefaults to `false`. Calling any passkey method while this flag is\ndisabled throws a descriptive error at call time." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Opt-in flags for experimental features. These APIs may change without\nnotice and are disabled by default.", + "tags": [ + { + "tag": "experimental", + "text": "" + } + ] + } + }, + { + "name": "fetch", + "type": { + "type": "nameOnly", + "name": "Fetch" + }, + "isOptional": true + }, + { + "name": "flowType", + "type": { + "type": "union", + "name": "AuthFlowType", + "subTypes": [ + { + "type": "literal", + "value": "implicit" + }, + { + "type": "literal", + "value": "pkce" + }, + null + ] + }, + "isOptional": true + }, + { + "name": "hasCustomAuthorizationHeader", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Set to \"true\" if there is a custom authorization header set globally.", + "tags": [ + { + "tag": "experimental", + "text": "" + } + ] + } + }, + { + "name": "headers", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true + }, + { + "name": "lock", + "type": { + "name": "LockFunc", + "type": "function", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Name of the lock to be acquired." + } + }, + { + "name": "acquireTimeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "If negative, no timeout should occur. If positive it\n should throw an Error with an `isAcquireTimeout`\n property set to true if the operation fails to be\n acquired after this much time (ms)." + } + }, + { + "name": "fn", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "R" + } + } + } + }, + "comment": { + "shortText": "The operation to execute when the lock is acquired." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "R" + } + } + } + }, + "isOptional": true, + "comment": { + "shortText": "Provide your own locking mechanism based on the environment. By default\nthe client coordinates refreshes itself (single-flight via\n`refreshingDeferred` + commit guard) and relies on the GoTrue server to\nresolve cross-tab refresh races. Passing a custom lock opts into a\nlegacy path that wraps every auth operation in your supplied lock — this\npath is preserved for backwards compatibility (typically React Native\n`processLock` or Node multi-process setups)." + } + }, + { + "name": "lockAcquireTimeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "The maximum time in milliseconds to wait for acquiring the custom lock\nsupplied via the `lock` option. Only consulted when a custom `lock` is\npassed — the default lockless path doesn't use this timeout." + } + }, + { + "name": "persistSession", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "skipAutoInitialize", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If true, skips automatic initialization in constructor. Useful for SSR\ncontexts where initialization timing must be controlled to prevent race\nconditions with HTTP response generation." + } + }, + { + "name": "storage", + "type": { + "type": "nameOnly", + "name": "SupportedStorage" + }, + "isOptional": true + }, + { + "name": "storageKey", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "throwOnError", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If there is an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response." + } + }, + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "userStorage", + "type": { + "type": "nameOnly", + "name": "SupportedStorage" + }, + "isOptional": true, + "comment": { + "shortText": "Stores the user object in a separate storage location from the rest of the session data. When non-null, `storage` will only store a JSON object containing the access and refresh token and some adjacent metadata, while `userStorage` will only contain the user object under the key `storageKey + '-user'`.\n\nWhen this option is set and cookie storage is used, `getSession()` and other functions that load a session from the cookie store might not return back a user. It's very important to always use `getUser()` to fetch a user object in those scenarios.", + "tags": [ + { + "tag": "experimental", + "text": "" + } + ] + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "GoTrueClient" + } + }, + "comment": { + "shortText": "Create a new client for use in the browser.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst { data, error } = await supabase.auth.getUser()\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport { GoTrueClient } from '@supabase/auth-js'\n\nconst auth = new GoTrueClient({\n url: 'https://xyzcompany.supabase.co/auth/v1',\n headers: { apikey: 'your-publishable-key' },\n storageKey: 'supabase-auth',\n})\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.dispose": { + "name": "@supabase/auth-js.GoTrueClient.dispose", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "Tears down the client's background work: stops the auto-refresh interval,\nremoves the `visibilitychange` listener, closes the cross-tab\n`BroadcastChannel`, and clears registered `onAuthStateChange` subscribers.\n\nCall this from cleanup hooks when the client is being replaced before\nits JS realm is destroyed. React Strict Mode and HMR are the common\ncases. Any in-flight `fetch` calls continue to completion and may still\nwrite to storage; dispose doesn't abort them or erase storage.\n\nLifecycle caveat: because in-flight refreshes are not aborted, a\ndisposed instance can still persist a rotated session to storage after\n`dispose()` returns. A subsequent `createClient` against the same\n`storageKey` will pick up that session on its next read. If you need\nstrict isolation between client lifecycles, await any pending auth\noperation before calling `dispose()` (or change the `storageKey` for\nthe replacement client).\n\nSafe to call repeatedly.", + "examples": [ + { + "id": "cleanup-on-react-unmount", + "name": "Cleanup on React unmount", + "code": "```ts\nuseEffect(() => {\n const client = createClient(...)\n return () => { client.auth.dispose() }\n}, [])\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.exchangeCodeForSession": { + "name": "@supabase/auth-js.GoTrueClient.exchangeCodeForSession", + "params": [ + { + "name": "authCode", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthTokenResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": { + "type": "literal", + "value": "bearer" + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Log in an existing user by exchanging an Auth Code issued during the PKCE flow.", + "text": "- Used when `flowType` is set to `pkce` in client options.", + "examples": [ + { + "id": "exchange-auth-code", + "name": "Exchange Auth Code", + "code": "```js\nsupabase.auth.exchangeCodeForSession('34e770dd-9ff9-416c-87fa-43b31d7ef225')\n```", + "response": "```json\n{\n \"data\": {\n session: {\n access_token: '',\n token_type: 'bearer',\n expires_in: 3600,\n expires_at: 1700000000,\n refresh_token: '',\n user: {\n id: '11111111-1111-1111-1111-111111111111',\n aud: 'authenticated',\n role: 'authenticated',\n email: 'example@email.com'\n email_confirmed_at: '2024-01-01T00:00:00Z',\n phone: '',\n confirmation_sent_at: '2024-01-01T00:00:00Z',\n confirmed_at: '2024-01-01T00:00:00Z',\n last_sign_in_at: '2024-01-01T00:00:00Z',\n app_metadata: {\n \"provider\": \"email\",\n \"providers\": [\n \"email\",\n \"\"\n ]\n },\n user_metadata: {\n email: 'email@email.com',\n email_verified: true,\n full_name: 'User Name',\n iss: '',\n name: 'User Name',\n phone_verified: false,\n provider_id: '',\n sub: ''\n },\n identities: [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"email@example.com\"\n },\n {\n \"identity_id\": \"33333333-3333-3333-3333-333333333333\",\n \"id\": \"\",\n \"user_id\": \"\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": true,\n \"full_name\": \"User Name\",\n \"iss\": \"\",\n \"name\": \"User Name\",\n \"phone_verified\": false,\n \"provider_id\": \"\",\n \"sub\": \"\"\n },\n \"provider\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n is_anonymous: false\n },\n provider_token: '',\n provider_refresh_token: ''\n },\n user: {\n id: '11111111-1111-1111-1111-111111111111',\n aud: 'authenticated',\n role: 'authenticated',\n email: 'example@email.com',\n email_confirmed_at: '2024-01-01T00:00:00Z',\n phone: '',\n confirmation_sent_at: '2024-01-01T00:00:00Z',\n confirmed_at: '2024-01-01T00:00:00Z',\n last_sign_in_at: '2024-01-01T00:00:00Z',\n app_metadata: {\n provider: 'email',\n providers: [\n \"email\",\n \"\"\n ]\n },\n user_metadata: {\n email: 'email@email.com',\n email_verified: true,\n full_name: 'User Name',\n iss: '',\n name: 'User Name',\n phone_verified: false,\n provider_id: '',\n sub: ''\n },\n identities: [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"email@example.com\"\n },\n {\n \"identity_id\": \"33333333-3333-3333-3333-333333333333\",\n \"id\": \"\",\n \"user_id\": \"\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": true,\n \"full_name\": \"User Name\",\n \"iss\": \"\",\n \"name\": \"User Name\",\n \"phone_verified\": false,\n \"provider_id\": \"\",\n \"sub\": \"\"\n },\n \"provider\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n is_anonymous: false\n },\n redirectType: null\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.getClaims": { + "name": "@supabase/auth-js.GoTrueClient.getClaims", + "params": [ + { + "name": "jwt", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "An optional specific JWT you wish to verify, not the one you\n can obtain from #getSession." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "allowExpired", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If set to `true` the `exp` claim will not be validated against the current time." + } + }, + { + "name": "jwks", + "type": { + "type": "object", + "properties": [ + { + "name": "keys", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "JWK", + "properties": [ + { + "name": "alg", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "key_ops", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + }, + { + "name": "kid", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "kty", + "type": { + "type": "union", + "subTypes": [ + null, + { + "type": "literal", + "value": "RSA" + }, + { + "type": "literal", + "value": "EC" + }, + { + "type": "literal", + "value": "oct" + } + ] + } + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "If set, this JSON Web Key Set is going to have precedence over the cached value available on the server." + } + }, + { + "name": "keys", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "JWK", + "properties": [ + { + "name": "alg", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "key_ops", + "type": { + "type": "array", + "elemType": "[Circular]" + } + }, + { + "name": "kid", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "kty", + "type": { + "type": "union", + "subTypes": [ + null, + "[Circular]", + "[Circular]", + "[Circular]" + ] + } + } + ] + } + }, + "isOptional": true, + "comment": { + "shortText": "" + } + } + ] + }, + "comment": { + "shortText": "Various additional options that allow you to customize the\n behavior of this method." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "claims", + "type": { + "type": "object", + "name": "JwtPayload", + "properties": [ + { + "name": "aal", + "type": { + "type": "union", + "name": "AuthenticatorAssuranceLevels", + "subTypes": [ + { + "type": "literal", + "value": "aal1" + }, + { + "type": "literal", + "value": "aal2" + }, + null + ] + } + }, + { + "name": "amr", + "type": { + "type": "union", + "subTypes": [ + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + { + "type": "array", + "elemType": { + "type": "object", + "name": "AMREntry", + "properties": [ + { + "name": "method", + "type": { + "type": "union", + "name": "AMRMethod", + "subTypes": [ + { + "type": "nameOnly", + "name": "['number']" + }, + null + ] + }, + "comment": { + "shortText": "Authentication method name." + } + }, + { + "name": "timestamp", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "Timestamp when the method was successfully used. Represents number of\nseconds since 1st January 1970 (UNIX epoch) in UTC." + } + } + ] + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Authentication Method References.\nSupports both RFC-8176 compliant format (string[]) and detailed format (AMREntry[]).\n- String format: ['password', 'otp'] - RFC-8176 compliant\n- Object format: [{ method: 'password', timestamp: 1234567890 }] - includes timestamps" + } + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + }, + "isOptional": true + }, + { + "name": "aud", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "exp", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "iat", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "is_anonymous", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "iss", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "jti", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "nbf", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "phone", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "ref", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "role", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "session_id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "sub", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + }, + "isOptional": true + } + ] + } + }, + { + "name": "header", + "type": { + "name": "JwtHeader", + "type": "object", + "properties": [ + { + "name": "alg", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "RS256" + }, + { + "type": "literal", + "value": "ES256" + }, + { + "type": "literal", + "value": "HS256" + }, + null + ] + } + }, + { + "name": "kid", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "typ", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "signature", + "type": { + "type": "nameOnly", + "name": "Uint8Array" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Extracts the JWT claims present in the access token by first verifying the\nJWT against the server's JSON Web Key Set endpoint\n`/.well-known/jwks.json` which is often cached, resulting in significantly\nfaster responses. Prefer this method over #getUser which always\nsends a request to the Auth server for each JWT.\n\nIf the project is not using an asymmetric JWT signing key (like ECC or\nRSA) it always sends a request to the Auth server (similar to #getUser) to verify the JWT.", + "text": "- Parses the user's [access token](/docs/guides/auth/sessions#access-token-jwt-claims) as a [JSON Web Token (JWT)](/docs/guides/auth/jwts) and returns its components if valid and not expired.\n- If your project is using asymmetric JWT signing keys, then the verification is done locally usually without a network request using the [WebCrypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API).\n- A network request is sent to your project's JWT signing key discovery endpoint `https://project-id.supabase.co/auth/v1/.well-known/jwks.json`, which is cached locally. If your environment is ephemeral, such as a Lambda function that is destroyed after every request, a network request will be sent for each new invocation. Supabase provides a network-edge cache providing fast responses for these situations.\n- If the user's access token is about to expire when calling this function, the user's session will first be refreshed before validating the JWT.\n- If your project is using a symmetric secret to sign the JWT, it always sends a request similar to `getUser()` to validate the JWT at the server before returning the decoded token. This is also used if the WebCrypto API is not available in the environment. Make sure you polyfill it in such situations.\n- The returned claims can be customized per project using the [Custom Access Token Hook](/docs/guides/auth/auth-hooks/custom-access-token-hook).", + "examples": [ + { + "id": "get-jwt-claims-header-and-signature", + "name": "Get JWT claims, header and signature", + "code": "```js\nconst { data, error } = await supabase.auth.getClaims()\n```", + "response": "```json\n{\n \"data\": {\n \"claims\": {\n \"aal\": \"aal1\",\n \"amr\": [{\n \"method\": \"email\",\n \"timestamp\": 1715766000\n }],\n \"app_metadata\": {},\n \"aud\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"exp\": 1715769600,\n \"iat\": 1715766000,\n \"is_anonymous\": false,\n \"iss\": \"https://project-id.supabase.co/auth/v1\",\n \"phone\": \"+13334445555\",\n \"role\": \"authenticated\",\n \"session_id\": \"11111111-1111-1111-1111-111111111111\",\n \"sub\": \"11111111-1111-1111-1111-111111111111\",\n \"user_metadata\": {}\n },\n \"header\": {\n \"alg\": \"RS256\",\n \"typ\": \"JWT\",\n \"kid\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"signature\": [/** Uint8Array */],\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.getSession": { + "name": "@supabase/auth-js.GoTrueClient.getSession", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "literal", + "value": null + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "literal", + "value": null + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Returns the session, refreshing it if necessary.\n\nThe session returned can be null if the session is not detected which can happen in the event a user is not signed-in or has logged out.\n\n**IMPORTANT:** This method loads values directly from the storage attached\nto the client. If that storage is based on request cookies for example,\nthe values in it may not be authentic and therefore it's strongly advised\nagainst using this method and its results in such circumstances. A warning\nwill be emitted if this is detected. Use #getUser() instead.", + "text": "- Since the introduction of [asymmetric JWT signing keys](/docs/guides/auth/signing-keys), this method is considered low-level and we encourage you to use `getClaims()` or `getUser()` instead.\n- Retrieves the current [user session](/docs/guides/auth/sessions) from the storage medium (local storage, cookies).\n- The session contains an access token (signed JWT), a refresh token and the user object.\n- If the session's access token is expired or is about to expire, this method will use the refresh token to refresh the session.\n- When using in a browser, or you've called `startAutoRefresh()` in your environment (React Native, etc.) this function always returns a valid access token without refreshing the session itself, as this is done in the background. This function returns very fast.\n- **IMPORTANT SECURITY NOTICE:** If using an insecure storage medium, such as cookies or request headers, the user object returned by this function **must not be trusted**. Always verify the JWT using `getClaims()` or your own JWT verification library to securely establish the user's identity and access. You can also use `getUser()` to fetch the user object directly from the Auth server for this purpose.\n- Cross-tab refresh races are handled by the GoTrue server (the rotated token from the first tab is returned to subsequent tabs via the parent-of-active mechanism), so no client-side serialization is needed.", + "examples": [ + { + "id": "get-the-session-data", + "name": "Get the session data", + "code": "```js\nconst { data, error } = await supabase.auth.getSession()\n```", + "response": "```json\n{\n \"data\": {\n \"session\": {\n \"access_token\": \"\",\n \"token_type\": \"bearer\",\n \"expires_in\": 3600,\n \"expires_at\": 1700000000,\n \"refresh_token\": \"\",\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n }\n }\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.getUser": { + "name": "@supabase/auth-js.GoTrueClient.getUser", + "params": [ + { + "name": "jwt", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Takes in an optional access token JWT. If no JWT is provided, the JWT from the current session is used." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "UserResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Gets the current user details if there is an existing session. This method\nperforms a network request to the Supabase Auth server, so the returned\nvalue is authentic and can be used to base authorization rules on.", + "text": "- This method fetches the user object from the database instead of local session.\n- This method is useful for checking if the user is authorized because it validates the user's access token JWT on the server.\n- Should always be used when checking for user authorization on the server. On the client, you can instead use `getSession().session.user` for faster results. `getSession` is insecure on the server.", + "examples": [ + { + "id": "get-the-logged-in-user-with-the-current-existing-session", + "name": "Get the logged in user with the current existing session", + "code": "```js\nconst { data: { user } } = await supabase.auth.getUser()\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "get-the-logged-in-user-with-a-custom-access-token-jwt", + "name": "Get the logged in user with a custom access token jwt", + "code": "```js\nconst { data: { user } } = await supabase.auth.getUser(jwt)\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.getUserIdentities": { + "name": "@supabase/auth-js.GoTrueClient.getUserIdentities", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Gets all the identities linked to a user.", + "text": "- The user needs to be signed in to call `getUserIdentities()`.", + "examples": [ + { + "id": "returns-a-list-of-identities-linked-to-the-user", + "name": "Returns a list of identities linked to the user", + "code": "```js\nconst { data, error } = await supabase.auth.getUserIdentities()\n```", + "response": "```json\n{\n \"data\": {\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"2024-01-01T00:00:00Z\",\n \"user_id\": \"2024-01-01T00:00:00Z\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ]\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.initialize": { + "name": "@supabase/auth-js.GoTrueClient.initialize", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "name": "InitializeResult", + "type": "object", + "properties": [ + { + "name": "error", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "AuthError" + }, + { + "type": "literal", + "value": null + } + ] + } + } + ] + } + } + }, + "comment": { + "shortText": "Initializes the client session either from the url or from storage.\nThis method is automatically called when instantiating the client, but should also be called\nmanually when checking for an error from an auth redirect (oauth, magiclink, password recovery, etc)." + } + }, + "@supabase/auth-js.GoTrueClient.isThrowOnErrorEnabled": { + "name": "@supabase/auth-js.GoTrueClient.isThrowOnErrorEnabled", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "boolean" + } + }, + "comment": { + "shortText": "Returns whether error throwing mode is enabled for this client." + } + }, + "@supabase/auth-js.GoTrueClient.linkIdentity": { + "name": "@supabase/auth-js.GoTrueClient.linkIdentity", + "params": [ + { + "name": "credentials", + "type": { + "name": "SignInWithOAuthCredentials", + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "queryParams", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "An object of query params" + } + }, + { + "name": "redirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "A URL to send the user to after they are confirmed." + } + }, + { + "name": "scopes", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "A space-separated list of scopes granted to the OAuth application." + } + }, + { + "name": "skipBrowserRedirect", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If set to true does not immediately redirect the current browser context to visit the OAuth authorization page for the provider." + } + } + ] + }, + "isOptional": true + }, + { + "name": "provider", + "type": { + "type": "union", + "name": "Provider", + "subTypes": [ + { + "type": "literal", + "value": "apple" + }, + { + "type": "literal", + "value": "azure" + }, + { + "type": "literal", + "value": "bitbucket" + }, + { + "type": "literal", + "value": "discord" + }, + { + "type": "literal", + "value": "facebook" + }, + { + "type": "literal", + "value": "figma" + }, + { + "type": "literal", + "value": "github" + }, + { + "type": "literal", + "value": "gitlab" + }, + { + "type": "literal", + "value": "google" + }, + { + "type": "literal", + "value": "kakao" + }, + { + "type": "literal", + "value": "keycloak" + }, + { + "type": "literal", + "value": "linkedin" + }, + { + "type": "literal", + "value": "linkedin_oidc" + }, + { + "type": "literal", + "value": "notion" + }, + { + "type": "literal", + "value": "slack" + }, + { + "type": "literal", + "value": "slack_oidc" + }, + { + "type": "literal", + "value": "spotify" + }, + { + "type": "literal", + "value": "twitch" + }, + { + "type": "literal", + "value": "twitter" + }, + { + "type": "literal", + "value": "x" + }, + { + "type": "literal", + "value": "workos" + }, + { + "type": "literal", + "value": "zoom" + }, + { + "type": "literal", + "value": "fly" + }, + null + ] + }, + "comment": { + "shortText": "One of the providers supported by GoTrue." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "OAuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "provider", + "type": { + "type": "union", + "name": "Provider", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + }, + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "provider", + "type": { + "type": "union", + "name": "Provider", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + }, + { + "name": "url", + "type": { + "type": "literal", + "value": null + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Links an oauth identity to an existing user.\nThis method supports the PKCE flow.", + "text": "- The **Enable Manual Linking** option must be enabled from your [project's authentication settings](/dashboard/project/_/auth/providers).\n- The user needs to be signed in to call `linkIdentity()`.\n- If the candidate identity is already linked to the existing user or another user, `linkIdentity()` will fail.\n- If `linkIdentity` is run in the browser, the user is automatically redirected to the returned URL. On the server, you should handle the redirect.", + "examples": [ + { + "id": "link-an-identity-to-a-user", + "name": "Link an identity to a user", + "code": "```js\nconst { data, error } = await supabase.auth.linkIdentity({\n provider: 'github'\n})\n```", + "response": "```json\n{\n data: {\n provider: 'github',\n url: \n },\n error: null\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "credentials", + "type": { + "name": "SignInWithIdTokenCredentials", + "type": "object", + "properties": [ + { + "name": "access_token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "If the ID token contains an `at_hash` claim, then the hash of this value is compared to the value in the ID token." + } + }, + { + "name": "nonce", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "If the ID token contains a `nonce` claim, then the hash of this value is compared to the value in the ID token." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + } + ] + }, + "isOptional": true + }, + { + "name": "provider", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "google" + }, + { + "type": "literal", + "value": "apple" + }, + { + "type": "literal", + "value": "azure" + }, + { + "type": "literal", + "value": "facebook" + }, + { + "type": "literal", + "value": "kakao" + }, + null, + null + ] + }, + "comment": { + "shortText": "Provider name or OIDC `iss` value identifying which provider should be used to verify the provided token. Supported names: `google`, `apple`, `azure`, `facebook`, `kakao`. Use the `custom:` prefix for custom OIDC providers (e.g. `custom:my-oidc-provider`)." + } + }, + { + "name": "token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "OIDC ID token issued by the specified provider. The `iss` claim in the ID token must match the supplied provider. Some ID tokens contain an `at_hash` which require that you provide an `access_token` value to be accepted properly. If the token contains a `nonce` claim you must supply the nonce used to obtain the ID token." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthTokenResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + } + } + ] + }, + "@supabase/auth-js.GoTrueClient.onAuthStateChange": { + "name": "@supabase/auth-js.GoTrueClient.onAuthStateChange", + "params": [ + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "event", + "type": { + "type": "union", + "name": "AuthChangeEvent", + "subTypes": [ + { + "type": "literal", + "value": "INITIAL_SESSION" + }, + { + "type": "literal", + "value": "PASSWORD_RECOVERY" + }, + { + "type": "literal", + "value": "SIGNED_IN" + }, + { + "type": "literal", + "value": "SIGNED_OUT" + }, + { + "type": "literal", + "value": "TOKEN_REFRESHED" + }, + { + "type": "literal", + "value": "USER_UPDATED" + }, + { + "type": "literal", + "value": "MFA_CHALLENGE_VERIFIED", + "name": "AuthChangeEventMFA" + } + ] + } + }, + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "A callback function to be invoked when an auth event happens." + } + } + ], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "subscription", + "type": { + "type": "object", + "name": "Subscription", + "properties": [ + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "event", + "type": { + "type": "union", + "name": "AuthChangeEvent", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + } + }, + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "The function to call every time there is an event. eg: (eventName) => {}" + } + }, + { + "name": "id", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "symbol" + } + ] + }, + "comment": { + "shortText": "A unique identifier for this subscription, set by the client.\nThis is an internal identifier used for managing callbacks and should not be\nrelied upon by application code. Use the unsubscribe() method to remove listeners." + } + }, + { + "name": "unsubscribe", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "Call this to remove the listener." + } + } + ] + } + } + ] + } + } + ] + } + }, + "comment": { + "shortText": "Receive a notification every time an auth event happens.\nSafe to use without an async function as callback.", + "text": "- Subscribes to important events occurring on the user's session.\n- Use on the frontend/client. It is less useful on the server.\n- Events are emitted across tabs to keep your application's UI up-to-date. Some events can fire very frequently, based on the number of tabs open. Use a quick and efficient callback function, and defer or debounce as many operations as you can to be performed outside of the callback.\n- Callbacks can be `async` and can safely call other Supabase auth methods (`getUser`, `setSession`, etc.) from inside the callback.\n- Keep callbacks quick. Events are awaited in order, so a slow callback delays subsequent events to subscribers in this tab.\n- Emitted events:\n - `INITIAL_SESSION`\n - Emitted right after the Supabase client is constructed and the initial session from storage is loaded.\n - `SIGNED_IN`\n - Emitted each time a user session is confirmed or re-established, including on user sign in and when refocusing a tab.\n - Avoid making assumptions as to when this event is fired, this may occur even when the user is already signed in. Instead, check the user object attached to the event to see if a new user has signed in and update your application's UI.\n - This event can fire very frequently depending on the number of tabs open in your application.\n - `SIGNED_OUT`\n - Emitted when the user signs out. This can be after:\n - A call to `supabase.auth.signOut()`.\n - After the user's session has expired for any reason:\n - User has signed out on another device.\n - The session has reached its timebox limit or inactivity timeout.\n - User has signed in on another device with single session per user enabled.\n - Check the [User Sessions](/docs/guides/auth/sessions) docs for more information.\n - Use this to clean up any local storage your application has associated with the user.\n - `TOKEN_REFRESHED`\n - Emitted each time a new access and refresh token are fetched for the signed in user.\n - It's best practice and highly recommended to extract the access token (JWT) and store it in memory for further use in your application.\n - Avoid frequent calls to `supabase.auth.getSession()` for the same purpose.\n - There is a background process that keeps track of when the session should be refreshed so you will always receive valid tokens by listening to this event.\n - The frequency of this event is related to the JWT expiry limit configured on your project.\n - `USER_UPDATED`\n - Emitted each time the `supabase.auth.updateUser()` method finishes successfully. Listen to it to update your application's UI based on new profile information.\n - `PASSWORD_RECOVERY`\n - Emitted instead of the `SIGNED_IN` event when the user lands on a page that includes a password recovery link in the URL.\n - Use it to show a UI to the user where they can [reset their password](/docs/guides/auth/passwords#resetting-a-users-password-forgot-password).", + "examples": [ + { + "id": "listen-to-auth-changes", + "name": "Listen to auth changes", + "code": "```js\nconst { data } = supabase.auth.onAuthStateChange((event, session) => {\n console.log(event, session)\n\n if (event === 'INITIAL_SESSION') {\n // handle initial session\n } else if (event === 'SIGNED_IN') {\n // handle sign in event\n } else if (event === 'SIGNED_OUT') {\n // handle sign out event\n } else if (event === 'PASSWORD_RECOVERY') {\n // handle password recovery event\n } else if (event === 'TOKEN_REFRESHED') {\n // handle token refreshed event\n } else if (event === 'USER_UPDATED') {\n // handle user updated event\n }\n})\n\n// call unsubscribe to remove the callback\ndata.subscription.unsubscribe()\n```" + }, + { + "id": "listen-to-sign-out", + "name": "Listen to sign out", + "code": "```js\nsupabase.auth.onAuthStateChange((event, session) => {\n if (event === 'SIGNED_OUT') {\n console.log('SIGNED_OUT', session)\n\n // clear local and session storage\n [\n window.localStorage,\n window.sessionStorage,\n ].forEach((storage) => {\n Object.entries(storage)\n .forEach(([key]) => {\n storage.removeItem(key)\n })\n })\n }\n})\n```", + "description": "Make sure you clear out any local data, such as local and session storage, after the client library has detected the user's sign out." + }, + { + "id": "store-oauth-provider-tokens-on-sign-in", + "name": "Store OAuth provider tokens on sign in", + "code": "```js\n// Register this immediately after calling createClient!\n// Because signInWithOAuth causes a redirect, you need to fetch the\n// provider tokens from the callback.\nsupabase.auth.onAuthStateChange((event, session) => {\n if (session && session.provider_token) {\n window.localStorage.setItem('oauth_provider_token', session.provider_token)\n }\n\n if (session && session.provider_refresh_token) {\n window.localStorage.setItem('oauth_provider_refresh_token', session.provider_refresh_token)\n }\n\n if (event === 'SIGNED_OUT') {\n window.localStorage.removeItem('oauth_provider_token')\n window.localStorage.removeItem('oauth_provider_refresh_token')\n }\n})\n```", + "description": "When using [OAuth (Social Login)](/docs/guides/auth/social-login) you sometimes wish to get access to the provider's access token and refresh token, in order to call provider APIs in the name of the user.\n\nFor example, if you are using [Sign in with Google](/docs/guides/auth/social-login/auth-google) you may want to use the provider token to call Google APIs on behalf of the user. Supabase Auth does not keep track of the provider access and refresh token, but does return them for you once, immediately after sign in. You can use the `onAuthStateChange` method to listen for the presence of the provider tokens and store them in local storage. You can further send them to your server's APIs for use on the backend.\n\nFinally, make sure you remove them from local storage on the `SIGNED_OUT` event. If the OAuth provider supports token revocation, make sure you call those APIs either from the frontend or schedule them to be called on the backend." + }, + { + "id": "use-react-context-for-the-user-s-session", + "name": "Use React Context for the User's session", + "code": "```js\nconst SessionContext = React.createContext(null)\n\nfunction main() {\n const [session, setSession] = React.useState(null)\n\n React.useEffect(() => {\n const {data: { subscription }} = supabase.auth.onAuthStateChange(\n (event, session) => {\n if (event === 'SIGNED_OUT') {\n setSession(null)\n } else if (session) {\n setSession(session)\n }\n })\n\n return () => {\n subscription.unsubscribe()\n }\n }, [])\n\n return (\n \n \n \n )\n}\n```", + "description": "Instead of relying on `supabase.auth.getSession()` within your React components, you can use a [React Context](https://react.dev/reference/react/createContext) to store the latest session information from the `onAuthStateChange` callback and access it that way." + }, + { + "id": "listen-to-password-recovery-events", + "name": "Listen to password recovery events", + "code": "```js\nsupabase.auth.onAuthStateChange((event, session) => {\n if (event === 'PASSWORD_RECOVERY') {\n console.log('PASSWORD_RECOVERY', session)\n // show screen to update user's password\n showPasswordResetScreen(true)\n }\n})\n```" + }, + { + "id": "listen-to-sign-in", + "name": "Listen to sign in", + "code": "```js\nsupabase.auth.onAuthStateChange((event, session) => {\n if (event === 'SIGNED_IN') console.log('SIGNED_IN', session)\n})\n```" + }, + { + "id": "listen-to-token-refresh", + "name": "Listen to token refresh", + "code": "```js\nsupabase.auth.onAuthStateChange((event, session) => {\n if (event === 'TOKEN_REFRESHED') console.log('TOKEN_REFRESHED', session)\n})\n```" + }, + { + "id": "listen-to-user-updates", + "name": "Listen to user updates", + "code": "```js\nsupabase.auth.onAuthStateChange((event, session) => {\n if (event === 'USER_UPDATED') console.log('USER_UPDATED', session)\n})\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "event", + "type": { + "type": "union", + "name": "AuthChangeEvent", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + } + }, + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "intrinsic", + "name": "void" + } + } + } + }, + "comment": { + "shortText": "A callback function to be invoked when an auth event happens." + } + } + ], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "subscription", + "type": { + "type": "object", + "name": "Subscription", + "properties": [ + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "event", + "type": { + "type": "union", + "name": "AuthChangeEvent", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + } + }, + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + ] + } + } + ], + "ret": { + "type": "[Circular]" + } + }, + "comment": { + "shortText": "The function to call every time there is an event. eg: (eventName) => {}" + } + }, + { + "name": "id", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "A unique identifier for this subscription, set by the client.\nThis is an internal identifier used for managing callbacks and should not be\nrelied upon by application code. Use the unsubscribe() method to remove listeners." + } + }, + { + "name": "unsubscribe", + "type": { + "type": "function", + "params": [], + "ret": { + "type": "[Circular]" + } + }, + "comment": { + "shortText": "Call this to remove the listener." + } + } + ] + } + } + ] + } + } + ] + } + } + } + ] + }, + "@supabase/auth-js.GoTrueClient.reauthenticate": { + "name": "@supabase/auth-js.GoTrueClient.reauthenticate", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + { + "type": "literal", + "value": null + } + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + { + "type": "literal", + "value": null + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Sends a reauthentication OTP to the user's email or phone number.\nRequires the user to be signed-in.", + "text": "- This method is used together with `updateUser()` when a user's password needs to be updated.\n- If you require your user to reauthenticate before updating their password, you need to enable the **Secure password change** option in your [project's email provider settings](/dashboard/project/_/auth/providers).\n- A user is only require to reauthenticate before updating their password if **Secure password change** is enabled and the user **hasn't recently signed in**. A user is deemed recently signed in if the session was created in the last 24 hours.\n- This method will send a nonce to the user's email. If the user doesn't have a confirmed email address, the method will send the nonce to the user's confirmed phone number instead.\n- After receiving the OTP, include it as the `nonce` in your `updateUser()` call to finalize the password change.", + "examples": [ + { + "id": "send-reauthentication-nonce", + "name": "Send reauthentication nonce", + "code": "```js\nconst { error } = await supabase.auth.reauthenticate()\n```", + "description": "Sends a reauthentication nonce to the user's email or phone number." + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.refreshSession": { + "name": "@supabase/auth-js.GoTrueClient.refreshSession", + "params": [ + { + "name": "currentSession", + "type": { + "type": "object", + "properties": [ + { + "name": "refresh_token", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The current session. If passed in, it must contain a refresh token." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + "[Circular]" + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "[Circular]" + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Returns a new session, regardless of expiry status.\nTakes in an optional current session. If not passed in, then refreshSession() will attempt to retrieve it from getSession().\nIf the current session's refresh token is invalid, an error will be thrown.", + "text": "- This method will refresh and return a new session whether the current one is expired or not.", + "examples": [ + { + "id": "refresh-session-using-the-current-session", + "name": "Refresh session using the current session", + "code": "```js\nconst { data, error } = await supabase.auth.refreshSession()\nconst { session, user } = data\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n },\n \"session\": {\n \"access_token\": \"\",\n \"token_type\": \"bearer\",\n \"expires_in\": 3600,\n \"expires_at\": 1700000000,\n \"refresh_token\": \"\",\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n }\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "refresh-session-using-a-refresh-token", + "name": "Refresh session using a refresh token", + "code": "```js\nconst { data, error } = await supabase.auth.refreshSession({ refresh_token })\nconst { session, user } = data\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.registerPasskey": { + "name": "@supabase/auth-js.GoTrueClient.registerPasskey", + "params": [ + { + "name": "credentials", + "type": { + "name": "RegisterPasskeyCredentials", + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyRegistrationVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "PasskeyMetadata", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "friendly_name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Register a passkey for the current authenticated user. Handles the full WebAuthn ceremony:\n1. Fetches registration challenge from server\n2. Prompts user via navigator.credentials.create()\n3. Verifies credential with server\n\nRequires an active session. Requires `auth.experimental.passkey: true`." + } + }, + "@supabase/auth-js.GoTrueClient.resend": { + "name": "@supabase/auth-js.GoTrueClient.resend", + "params": [ + { + "name": "credentials", + "type": { + "type": "union", + "name": "ResendParams", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "emailRedirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "A URL to send the user to after they have signed-in." + } + } + ] + }, + "isOptional": true + }, + { + "name": "type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "signup" + }, + { + "type": "literal", + "value": "email_change" + } + ] + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + } + ] + }, + "isOptional": true + }, + { + "name": "phone", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "sms" + }, + { + "type": "literal", + "value": "phone_change" + } + ] + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthOtpResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "messageId", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "literal", + "value": null + } + ] + }, + "isOptional": true + }, + { + "name": "session", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "user", + "type": { + "type": "literal", + "value": null + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "messageId", + "type": "[Circular]" + }, + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Resends an existing signup confirmation email, email change email, SMS OTP or phone change OTP.", + "text": "- Resends a signup confirmation, email change or phone change email to the user.\n- Passwordless sign-ins can be resent by calling the `signInWithOtp()` method again.\n- Password recovery emails can be resent by calling the `resetPasswordForEmail()` method again.\n- This method will only resend an email or phone OTP to the user if there was an initial signup, email change or phone change request being made(note: For existing users signing in with OTP, you should use `signInWithOtp()` again to resend the OTP).\n- You can specify a redirect url when you resend an email link using the `emailRedirectTo` option.", + "examples": [ + { + "id": "resend-an-email-signup-confirmation", + "name": "Resend an email signup confirmation", + "code": "```js\nconst { error } = await supabase.auth.resend({\n type: 'signup',\n email: 'email@example.com',\n options: {\n emailRedirectTo: 'https://example.com/welcome'\n }\n})\n```", + "description": "Resends the email signup confirmation to the user" + }, + { + "id": "resend-a-phone-signup-confirmation", + "name": "Resend a phone signup confirmation", + "code": "```js\nconst { error } = await supabase.auth.resend({\n type: 'sms',\n phone: '1234567890'\n})\n```", + "description": "Resends the phone signup confirmation email to the user" + }, + { + "id": "resend-email-change-email", + "name": "Resend email change email", + "code": "```js\nconst { error } = await supabase.auth.resend({\n type: 'email_change',\n email: 'email@example.com'\n})\n```", + "description": "Resends the email change email to the user" + }, + { + "id": "resend-phone-change-otp", + "name": "Resend phone change OTP", + "code": "```js\nconst { error } = await supabase.auth.resend({\n type: 'phone_change',\n phone: '1234567890'\n})\n```", + "description": "Resends the phone change OTP to the user" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.resetPasswordForEmail": { + "name": "@supabase/auth-js.GoTrueClient.resetPasswordForEmail", + "params": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The email address of the user." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "redirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The URL to send the user to after they click the password reset link." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Sends a password reset request to an email address. This method supports the PKCE flow.", + "text": "- The password reset flow consist of 2 broad steps: (i) Allow the user to login via the password reset link; (ii) Update the user's password.\n- The `resetPasswordForEmail()` only sends a password reset link to the user's email.\nTo update the user's password, see [`updateUser()`](/docs/reference/javascript/auth-updateuser).\n- A `PASSWORD_RECOVERY` event will be emitted when the password recovery link is clicked.\nYou can use [`onAuthStateChange()`](/docs/reference/javascript/auth-onauthstatechange) to listen and invoke a callback function on these events.\n- When the user clicks the reset link in the email they are redirected back to your application.\nYou can configure the URL that the user is redirected to with the `redirectTo` parameter.\nSee [redirect URLs and wildcards](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls) to add additional redirect URLs to your project.\n- After the user has been redirected successfully, prompt them for a new password and call `updateUser()`:\n```js\nconst { data, error } = await supabase.auth.updateUser({\n password: new_password\n})\n```", + "examples": [ + { + "id": "reset-password", + "name": "Reset password", + "code": "```js\nconst { data, error } = await supabase.auth.resetPasswordForEmail(email, {\n redirectTo: 'https://example.com/update-password',\n})\n```", + "response": "```json\n{\n data: {}\n error: null\n}\n```" + }, + { + "id": "reset-password-react", + "name": "Reset password (React)", + "code": "```js\n/**\n * Step 1: Send the user an email to get a password reset token.\n * This email contains a link which sends the user back to your application.\n */\nconst { data, error } = await supabase.auth\n .resetPasswordForEmail('user@email.com')\n\n/**\n * Step 2: Once the user is redirected back to your application,\n * ask the user to reset their password.\n */\n useEffect(() => {\n supabase.auth.onAuthStateChange(async (event, session) => {\n if (event == \"PASSWORD_RECOVERY\") {\n const newPassword = prompt(\"What would you like your new password to be?\");\n const { data, error } = await supabase.auth\n .updateUser({ password: newPassword })\n\n if (data) alert(\"Password updated successfully!\")\n if (error) alert(\"There was an error updating your password.\")\n }\n })\n }, [])\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.setSession": { + "name": "@supabase/auth-js.GoTrueClient.setSession", + "params": [ + { + "name": "currentSession", + "type": { + "type": "object", + "properties": [ + { + "name": "access_token", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "refresh_token", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "comment": { + "shortText": "The current session that minimally contains an access token and refresh token." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + "[Circular]" + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "[Circular]" + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Sets the session data from the current session. If the current session is expired, setSession will take care of refreshing it to obtain a new session.\nIf the refresh token or access token in the current session is invalid, an error will be thrown.", + "text": "- This method sets the session using an `access_token` and `refresh_token`.\n- If successful, a `SIGNED_IN` event is emitted.", + "examples": [ + { + "id": "set-the-session", + "name": "Set the session", + "code": "```js\n const { data, error } = await supabase.auth.setSession({\n access_token,\n refresh_token\n })\n```", + "description": "Sets the session data from an access_token and refresh_token, then returns an auth response or error.", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n },\n \"session\": {\n \"access_token\": \"\",\n \"refresh_token\": \"\",\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"11111111-1111-1111-1111-111111111111\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"2024-01-01T00:00:00Z\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n },\n \"token_type\": \"bearer\",\n \"expires_in\": 3500,\n \"expires_at\": 1700000000\n }\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.signInAnonymously": { + "name": "@supabase/auth-js.GoTrueClient.signInAnonymously", + "params": [ + { + "name": "credentials", + "type": { + "name": "SignInAnonymouslyCredentials", + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "object" + }, + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.\n\nThe `data` should be a JSON object that includes user-specific info, such as their first and last name." + } + } + ] + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + "[Circular]" + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "[Circular]" + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a new anonymous user.", + "text": "- Returns an anonymous user\n- It is recommended to set up captcha for anonymous sign-ins to prevent abuse. You can pass in the captcha token in the `options` param.", + "examples": [ + { + "id": "create-an-anonymous-user", + "name": "Create an anonymous user", + "code": "```js\nconst { data, error } = await supabase.auth.signInAnonymously({\n options: {\n captchaToken\n }\n});\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"\",\n \"phone\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {},\n \"user_metadata\": {},\n \"identities\": [],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": true\n },\n \"session\": {\n \"access_token\": \"\",\n \"token_type\": \"bearer\",\n \"expires_in\": 3600,\n \"expires_at\": 1700000000,\n \"refresh_token\": \"\",\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"\",\n \"phone\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {},\n \"user_metadata\": {},\n \"identities\": [],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": true\n }\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "create-an-anonymous-user-with-custom-user-metadata", + "name": "Create an anonymous user with custom user metadata", + "code": "```js\nconst { data, error } = await supabase.auth.signInAnonymously({\n options: {\n data\n }\n})\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.signInWithIdToken": { + "name": "@supabase/auth-js.GoTrueClient.signInWithIdToken", + "params": [ + { + "name": "credentials", + "type": { + "name": "SignInWithIdTokenCredentials", + "type": "object", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "If the ID token contains an `at_hash` claim, then the hash of this value is compared to the value in the ID token." + } + }, + { + "name": "nonce", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "If the ID token contains a `nonce` claim, then the hash of this value is compared to the value in the ID token." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + } + ] + }, + "isOptional": true + }, + { + "name": "provider", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + null, + null + ] + }, + "comment": { + "shortText": "Provider name or OIDC `iss` value identifying which provider should be used to verify the provided token. Supported names: `google`, `apple`, `azure`, `facebook`, `kakao`. Use the `custom:` prefix for custom OIDC providers (e.g. `custom:my-oidc-provider`)." + } + }, + { + "name": "token", + "type": "[Circular]", + "comment": { + "shortText": "OIDC ID token issued by the specified provider. The `iss` claim in the ID token must match the supplied provider. Some ID tokens contain an `at_hash` which require that you provide an `access_token` value to be accepted properly. If the token contains a `nonce` claim you must supply the nonce used to obtain the ID token." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthTokenResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Allows signing in with an OIDC ID token. The authentication provider used\nshould be enabled and configured.", + "text": "- Use an ID token to sign in.\n- Especially useful when implementing sign in using native platform dialogs in mobile or desktop apps using Sign in with Apple or Sign in with Google on iOS and Android.\n- You can also use Google's [One Tap](https://developers.google.com/identity/gsi/web/guides/display-google-one-tap) and [Automatic sign-in](https://developers.google.com/identity/gsi/web/guides/automatic-sign-in-sign-out) via this API.", + "examples": [ + { + "id": "sign-in-using-id-token", + "name": "Sign In using ID Token", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithIdToken({\n provider: 'google',\n token: 'your-id-token'\n})\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n ...\n },\n \"user_metadata\": {\n ...\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"provider\": \"google\",\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n },\n \"session\": {\n \"access_token\": \"\",\n \"token_type\": \"bearer\",\n \"expires_in\": 3600,\n \"expires_at\": 1700000000,\n \"refresh_token\": \"\",\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n ...\n },\n \"user_metadata\": {\n ...\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"provider\": \"google\",\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n }\n }\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.signInWithOAuth": { + "name": "@supabase/auth-js.GoTrueClient.signInWithOAuth", + "params": [ + { + "name": "credentials", + "type": { + "name": "SignInWithOAuthCredentials", + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "queryParams", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "An object of query params" + } + }, + { + "name": "redirectTo", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A URL to send the user to after they are confirmed." + } + }, + { + "name": "scopes", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A space-separated list of scopes granted to the OAuth application." + } + }, + { + "name": "skipBrowserRedirect", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "If set to true does not immediately redirect the current browser context to visit the OAuth authorization page for the provider." + } + } + ] + }, + "isOptional": true + }, + { + "name": "provider", + "type": { + "type": "union", + "name": "Provider", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + }, + "comment": { + "shortText": "One of the providers supported by GoTrue." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "OAuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "provider", + "type": { + "type": "union", + "name": "Provider", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + }, + { + "name": "url", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "provider", + "type": { + "type": "union", + "name": "Provider", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + }, + { + "name": "url", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Log in an existing user via a third-party provider.\nThis method supports the PKCE flow.", + "text": "- This method is used for signing in using [Social Login (OAuth) providers](/docs/guides/auth#configure-third-party-providers).\n- It works by redirecting your application to the provider's authorization screen, before bringing back the user to your app.", + "examples": [ + { + "id": "sign-in-using-a-third-party-provider", + "name": "Sign in using a third-party provider", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithOAuth({\n provider: 'github'\n})\n```", + "response": "```json\n{\n data: {\n provider: 'github',\n url: \n },\n error: null\n}\n```" + }, + { + "id": "sign-in-using-a-third-party-provider-with-redirect", + "name": "Sign in using a third-party provider with redirect", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithOAuth({\n provider: 'github',\n options: {\n redirectTo: 'https://example.com/welcome'\n }\n})\n```", + "description": "- When the OAuth provider successfully authenticates the user, they are redirected to the URL specified in the `redirectTo` parameter. This parameter defaults to the [`SITE_URL`](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls). It does not redirect the user immediately after invoking this method.\n- See [redirect URLs and wildcards](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls) to add additional redirect URLs to your project." + }, + { + "id": "sign-in-with-scopes-and-access-provider-tokens", + "name": "Sign in with scopes and access provider tokens", + "code": "```js\n// Register this immediately after calling createClient!\n// Because signInWithOAuth causes a redirect, you need to fetch the\n// provider tokens from the callback.\nsupabase.auth.onAuthStateChange((event, session) => {\n if (session && session.provider_token) {\n window.localStorage.setItem('oauth_provider_token', session.provider_token)\n }\n\n if (session && session.provider_refresh_token) {\n window.localStorage.setItem('oauth_provider_refresh_token', session.provider_refresh_token)\n }\n\n if (event === 'SIGNED_OUT') {\n window.localStorage.removeItem('oauth_provider_token')\n window.localStorage.removeItem('oauth_provider_refresh_token')\n }\n})\n\n// Call this on your Sign in with GitHub button to initiate OAuth\n// with GitHub with the requested elevated scopes.\nawait supabase.auth.signInWithOAuth({\n provider: 'github',\n options: {\n scopes: 'repo gist notifications'\n }\n})\n```", + "description": "If you need additional access from an OAuth provider, in order to access provider specific APIs in the name of the user, you can do this by passing in the scopes the user should authorize for your application. Note that the `scopes` option takes in **a space-separated list** of scopes.\n\nBecause OAuth sign-in often includes redirects, you should register an `onAuthStateChange` callback immediately after you create the Supabase client. This callback will listen for the presence of `provider_token` and `provider_refresh_token` properties on the `session` object and store them in local storage. The client library will emit these values **only once** immediately after the user signs in. You can then access them by looking them up in local storage, or send them to your backend servers for further processing.\n\nFinally, make sure you remove them from local storage on the `SIGNED_OUT` event. If the OAuth provider supports token revocation, make sure you call those APIs either from the frontend or schedule them to be called on the backend." + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.signInWithOtp": { + "name": "@supabase/auth-js.GoTrueClient.signInWithOtp", + "params": [ + { + "name": "credentials", + "type": { + "type": "union", + "name": "SignInWithPasswordlessCredentials", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's email address." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "object" + }, + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.\n\nThe `data` should be a JSON object that includes user-specific info, such as their first and last name." + } + }, + { + "name": "emailRedirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The redirect url embedded in the email link" + } + }, + { + "name": "shouldCreateUser", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If set to false, this method will not create a new user. Defaults to true." + } + } + ] + }, + "isOptional": true + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "channel", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "sms" + }, + { + "type": "literal", + "value": "whatsapp" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Messaging channel to use (e.g. whatsapp or sms)" + } + }, + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "object" + }, + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.\n\nThe `data` should be a JSON object that includes user-specific info, such as their first and last name." + } + }, + { + "name": "shouldCreateUser", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If set to false, this method will not create a new user. Defaults to true." + } + } + ] + }, + "isOptional": true + }, + { + "name": "phone", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's phone number." + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthOtpResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "messageId", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true + }, + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "messageId", + "type": "[Circular]" + }, + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Log in a user using magiclink or a one-time password (OTP).\n\nIf the `{{ .ConfirmationURL }}` variable is specified in the email template, a magiclink will be sent.\nIf the `{{ .Token }}` variable is specified in the email template, an OTP will be sent.\nIf you're using phone sign-ins, only an OTP will be sent. You won't be able to send a magiclink for phone sign-ins.\n\nBe aware that you may get back an error message that will not distinguish\nbetween the cases where the account does not exist or, that the account\ncan only be accessed via social login.\n\nDo note that you will need to configure a Whatsapp sender on Twilio\nif you are using phone sign in with the 'whatsapp' channel. The whatsapp\nchannel is not supported on other providers\nat this time.\nThis method supports PKCE when an email is passed.", + "text": "- Requires either an email or phone number.\n- This method is used for passwordless sign-ins where a OTP is sent to the user's email or phone number.\n- If the user doesn't exist, `signInWithOtp()` will signup the user instead. To restrict this behavior, you can set `shouldCreateUser` in `SignInWithPasswordlessCredentials.options` to `false`.\n- If you're using an email, you can configure whether you want the user to receive a magiclink or a OTP.\n- If you're using phone, you can configure whether you want the user to receive a OTP.\n- The magic link's destination URL is determined by the [`SITE_URL`](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls).\n- See [redirect URLs and wildcards](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls) to add additional redirect URLs to your project.\n- Magic links and OTPs share the same implementation. To send users a one-time code instead of a magic link, [modify the magic link email template](/dashboard/project/_/auth/templates) to include `{{ .Token }}` instead of `{{ .ConfirmationURL }}`.\n- See our [Twilio Phone Auth Guide](/docs/guides/auth/phone-login?showSMSProvider=Twilio) for details about configuring WhatsApp sign in.", + "examples": [ + { + "id": "sign-in-with-email", + "name": "Sign in with email", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithOtp({\n email: 'example@email.com',\n options: {\n emailRedirectTo: 'https://example.com/welcome'\n }\n})\n```", + "description": "The user will be sent an email which contains either a magiclink or a OTP or both. By default, a given user can only request a OTP once every 60 seconds.", + "response": "```json\n{\n \"data\": {\n \"user\": null,\n \"session\": null\n },\n \"error\": null\n}\n```" + }, + { + "id": "sign-in-with-sms-otp", + "name": "Sign in with SMS OTP", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithOtp({\n phone: '+13334445555',\n})\n```", + "description": "The user will be sent a SMS which contains a OTP. By default, a given user can only request a OTP once every 60 seconds." + }, + { + "id": "sign-in-with-whatsapp-otp", + "name": "Sign in with WhatsApp OTP", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithOtp({\n phone: '+13334445555',\n options: {\n channel:'whatsapp',\n }\n})\n```", + "description": "The user will be sent a WhatsApp message which contains a OTP. By default, a given user can only request a OTP once every 60 seconds. Note that a user will need to have a valid WhatsApp account that is linked to Twilio in order to use this feature." + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.signInWithPasskey": { + "name": "@supabase/auth-js.GoTrueClient.signInWithPasskey", + "params": [ + { + "name": "credentials", + "type": { + "name": "SignInWithPasskeyCredentials", + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyAuthenticationVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + { + "type": "literal", + "value": null + } + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + { + "type": "literal", + "value": null + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Sign in with a passkey. Handles the full WebAuthn ceremony:\n1. Fetches authentication challenge from server\n2. Prompts user via navigator.credentials.get()\n3. Verifies credential with server and creates session\n\nRequires `auth.experimental.passkey: true`." + } + }, + "@supabase/auth-js.GoTrueClient.signInWithPassword": { + "name": "@supabase/auth-js.GoTrueClient.signInWithPassword", + "params": [ + { + "name": "credentials", + "type": { + "type": "nameOnly", + "name": "SignInWithPasswordCredentials" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthTokenResponsePassword", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + }, + { + "name": "weakPassword", + "type": { + "name": "WeakPassword", + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "reasons", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "WeakPasswordReasons" + } + } + } + ] + }, + "isOptional": true + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + }, + { + "name": "weakPassword", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Log in an existing user with an email and password or phone and password.\n\nBe aware that you may get back an error message that will not distinguish\nbetween the cases where the account does not exist or that the\nemail/phone and password combination is wrong or that the account can only\nbe accessed via social login.", + "text": "- Requires either an email and password or a phone number and password.", + "examples": [ + { + "id": "sign-in-with-email-and-password", + "name": "Sign in with email and password", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithPassword({\n email: 'example@email.com',\n password: 'example-password',\n})\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {},\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\"\n },\n \"session\": {\n \"access_token\": \"\",\n \"token_type\": \"bearer\",\n \"expires_in\": 3600,\n \"expires_at\": 1700000000,\n \"refresh_token\": \"\",\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {},\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\"\n }\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "sign-in-with-phone-and-password", + "name": "Sign in with phone and password", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithPassword({\n phone: '+13334445555',\n password: 'some-password',\n})\n```" + }, + { + "id": "handling-errors", + "name": "Handling errors", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithPassword({\n email: 'example@email.com',\n password: 'example-password',\n})\nif (error) {\n console.error(error)\n return\n}\n```", + "description": "Log the full `error` object so fields like `code`, `status`, and `name` aren't hidden. The `error.code` (e.g. `'invalid_credentials'`, `'email_not_confirmed'`) is often more useful for branching than `error.message`, and the full object surfaces both." + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.signInWithSSO": { + "name": "@supabase/auth-js.GoTrueClient.signInWithSSO", + "params": [ + { + "name": "params", + "type": { + "type": "union", + "name": "SignInWithSSO", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "redirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "A URL to send the user to after they have signed-in." + } + }, + { + "name": "skipBrowserRedirect", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If set to true, the redirect will not happen on the client side.\nThis parameter is used when you wish to handle the redirect yourself.\nDefaults to false." + } + } + ] + }, + "isOptional": true + }, + { + "name": "providerId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "UUID of the SSO provider to invoke single-sign on to." + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "domain", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Domain name of the organization for which to invoke single-sign on." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "redirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "A URL to send the user to after they have signed-in." + } + }, + { + "name": "skipBrowserRedirect", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If set to true, the redirect will not happen on the client side.\nThis parameter is used when you wish to handle the redirect yourself.\nDefaults to false." + } + } + ] + }, + "isOptional": true + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "SSOResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "URL to open in a browser which will complete the sign-in flow by\ntaking the user to the identity provider's authentication flow.\n\nOn browsers you can set the URL to `window.location.href` to take\nthe user to the authentication flow." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Attempts a single-sign on using an enterprise Identity Provider. A\nsuccessful SSO attempt will redirect the current page to the identity\nprovider authorization page. The redirect URL is implementation and SSO\nprotocol specific.\n\nYou can use it by providing a SSO domain. Typically you can extract this\ndomain by asking users for their email address. If this domain is\nregistered on the Auth instance the redirect will use that organization's\ncurrently active SSO Identity Provider for the login.\n\nIf you have built an organization-specific login page, you can use the\norganization's SSO Identity Provider UUID directly instead.", + "text": "- Before you can call this method you need to [establish a connection](/docs/guides/auth/sso/auth-sso-saml#managing-saml-20-connections) to an identity provider. Use the [CLI commands](/docs/reference/cli/supabase-sso) to do this.\n- If you've associated an email domain to the identity provider, you can use the `domain` property to start a sign-in flow.\n- In case you need to use a different way to start the authentication flow with an identity provider, you can use the `providerId` property. For example:\n - Mapping specific user email addresses with an identity provider.\n - Using different hints to identity the identity provider to be used by the user, like a company-specific page, IP address or other tracking information.", + "examples": [ + { + "id": "sign-in-with-email-domain", + "name": "Sign in with email domain", + "code": "```js\n // You can extract the user's email domain and use it to trigger the\n // authentication flow with the correct identity provider.\n\n const { data, error } = await supabase.auth.signInWithSSO({\n domain: 'company.com'\n })\n\n if (data?.url) {\n // redirect the user to the identity provider's authentication flow\n window.location.href = data.url\n }\n```" + }, + { + "id": "sign-in-with-provider-uuid", + "name": "Sign in with provider UUID", + "code": "```js\n // Useful when you need to map a user's sign in request according\n // to different rules that can't use email domains.\n\n const { data, error } = await supabase.auth.signInWithSSO({\n providerId: '21648a9d-8d5a-4555-a9d1-d6375dc14e92'\n })\n\n if (data?.url) {\n // redirect the user to the identity provider's authentication flow\n window.location.href = data.url\n }\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.signInWithWeb3": { + "name": "@supabase/auth-js.GoTrueClient.signInWithWeb3", + "params": [ + { + "name": "credentials", + "type": { + "type": "union", + "name": "Web3Credentials", + "subTypes": [ + { + "type": "union", + "name": "SolanaWeb3Credentials", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "chain", + "type": { + "type": "literal", + "value": "solana" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "signInWithSolana", + "type": { + "type": "nameOnly", + "name": "Partial" + }, + "isOptional": true + }, + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URL to use with the wallet interface. Some wallets do not allow signing a message for URLs different from the current page." + } + } + ] + }, + "isOptional": true + }, + { + "name": "statement", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Optional statement to include in the Sign in with Solana message. Must not include new line characters. Most wallets like Phantom **require specifying a statement!**" + } + }, + { + "name": "wallet", + "type": { + "name": "SolanaWallet", + "type": "object", + "properties": [ + { + "name": "publicKey", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "toBase58", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "string" + } + } + } + } + ] + }, + { + "type": "literal", + "value": null + } + ] + }, + "isOptional": true + }, + { + "name": "signIn", + "type": { + "type": "function", + "params": [ + { + "name": "inputs", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "SolanaSignInInput" + } + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "SolanaSignInOutput" + }, + { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "SolanaSignInOutput" + } + } + ] + } + } + } + }, + "isOptional": true + }, + { + "name": "signMessage", + "type": { + "type": "function", + "params": [ + { + "name": "message", + "type": { + "type": "nameOnly", + "name": "Uint8Array" + } + }, + { + "name": "encoding", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "utf8" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Uint8Array" + } + }, + { + "type": "intrinsic", + "name": "undefined" + } + ] + } + } + }, + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Wallet interface to use. If not specified will default to `window.solana`." + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "chain", + "type": { + "type": "literal", + "value": "solana" + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Sign in with Solana compatible message. Must include `Issued At`, `URI` and `Version`." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + } + ] + }, + "isOptional": true + }, + { + "name": "signature", + "type": { + "type": "nameOnly", + "name": "Uint8Array" + }, + "comment": { + "shortText": "Ed25519 signature of the message." + } + } + ] + } + ] + }, + { + "type": "union", + "name": "EthereumWeb3Credentials", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "chain", + "type": { + "type": "literal", + "value": "ethereum" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "signInWithEthereum", + "type": { + "type": "nameOnly", + "name": "Partial" + }, + "isOptional": true + }, + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URL to use with the wallet interface. Some wallets do not allow signing a message for URLs different from the current page." + } + } + ] + }, + "isOptional": true + }, + { + "name": "statement", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Optional statement to include in the Sign in with Ethereum message. Must not include new line characters. Most wallets like Phantom **require specifying a statement!**" + } + }, + { + "name": "wallet", + "type": { + "type": "nameOnly", + "name": "EthereumWallet" + }, + "isOptional": true, + "comment": { + "shortText": "Wallet interface to use. If not specified will default to `window.ethereum`." + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "chain", + "type": { + "type": "literal", + "value": "ethereum" + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Sign in with Ethereum compatible message. Must include `Issued At`, `URI` and `Version`." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + } + ] + }, + "isOptional": true + }, + { + "name": "signature", + "type": { + "type": "nameOnly", + "name": "Hex" + }, + "comment": { + "shortText": "Ethereum curve (secp256k1) signature of the message." + } + } + ] + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "user", + "type": { + "type": "literal", + "value": null + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Signs in a user by verifying a message signed by the user's private key.\nSupports Ethereum (via Sign-In-With-Ethereum) & Solana (Sign-In-With-Solana) standards,\nboth of which derive from the EIP-4361 standard\nWith slight variation on Solana's side.", + "text": "- Uses a Web3 (Ethereum, Solana) wallet to sign a user in.\n- Read up on the [potential for abuse](/docs/guides/auth/auth-web3#potential-for-abuse) before using it.", + "examples": [ + { + "id": "sign-in-with-solana-or-ethereum-window-api", + "name": "Sign in with Solana or Ethereum (Window API)", + "code": "```js\n // uses window.ethereum for the wallet\n const { data, error } = await supabase.auth.signInWithWeb3({\n chain: 'ethereum',\n statement: 'I accept the Terms of Service at https://example.com/tos'\n })\n\n // uses window.solana for the wallet\n const { data, error } = await supabase.auth.signInWithWeb3({\n chain: 'solana',\n statement: 'I accept the Terms of Service at https://example.com/tos'\n })\n```" + }, + { + "id": "sign-in-with-ethereum-message-and-signature", + "name": "Sign in with Ethereum (Message and Signature)", + "code": "```js\n const { data, error } = await supabase.auth.signInWithWeb3({\n chain: 'ethereum',\n message: '',\n signature: '',\n })\n```" + }, + { + "id": "sign-in-with-solana-brave", + "name": "Sign in with Solana (Brave)", + "code": "```js\n const { data, error } = await supabase.auth.signInWithWeb3({\n chain: 'solana',\n statement: 'I accept the Terms of Service at https://example.com/tos',\n wallet: window.braveSolana\n })\n```" + }, + { + "id": "sign-in-with-solana-wallet-adapter", + "name": "Sign in with Solana (Wallet Adapter)", + "code": "```jsx\n function SignInButton() {\n const wallet = useWallet()\n\n return (\n <>\n {wallet.connected ? (\n {\n supabase.auth.signInWithWeb3({\n chain: 'solana',\n statement: 'I accept the Terms of Service at https://example.com/tos',\n wallet,\n })\n }}\n >\n Sign in with Solana\n \n ) : (\n \n )}\n \n )\n}\n\nfunction App() {\n const endpoint = clusterApiUrl('devnet')\n const wallets = useMemo(() => [], [])\n\n return (\n \n \n \n \n \n \n \n )\n}\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.signOut": { + "name": "@supabase/auth-js.GoTrueClient.signOut", + "params": [ + { + "name": "options", + "type": { + "name": "SignOut", + "type": "object", + "properties": [ + { + "name": "scope", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "global" + }, + { + "type": "literal", + "value": "local" + }, + { + "type": "literal", + "value": "others" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Determines which sessions should be\nlogged out. Global means all\nsessions by this account. Local\nmeans only this session. Others\nmeans all other sessions except the\ncurrent one. When using others,\nthere is no sign-out event fired on\nthe current session!" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "object", + "properties": [ + { + "name": "error", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "nameOnly", + "name": "AuthError" + } + ] + } + } + ] + } + } + }, + "comment": { + "shortText": "Inside a browser context, `signOut()` will remove the logged in user from the browser session and log them out - removing all items from localstorage and then trigger a `\"SIGNED_OUT\"` event.\n\nFor server-side management, you can revoke all refresh tokens for a user by passing a user's JWT through to `auth.api.signOut(JWT: string)`.\nThere is no way to revoke a user's access token jwt until it expires. It is recommended to set a shorter expiry on the jwt for this reason.\n\nIf using `others` scope, no `SIGNED_OUT` event is fired!\n\n**Warning:** the default `scope` is `'global'`. This signs the user out of\n**every device they are currently signed in on**, not just the current\ntab/session. If you only want to sign the user out of the current session\n(the behavior most other auth libraries default to), pass\n`{ scope: 'local' }` explicitly.", + "text": "- In order to use the `signOut()` method, the user needs to be signed in first.\n- By default, `signOut()` uses the **global** scope, which signs out the user\n on every device they are signed in on (not just the current one). Pass\n `{ scope: 'local' }` to only sign out the current session. This is\n usually what apps want on a \"Sign out\" button, especially when users\n sign in from multiple devices and do not expect signing out of one to\n terminate the others.\n- Since Supabase Auth uses JWTs for authentication, the access token JWT will be valid until it's expired. When the user signs out, Supabase revokes the refresh token and deletes the JWT from the client-side. This does not revoke the JWT and it will still be valid until it expires.", + "examples": [ + { + "id": "sign-out-of-every-device-global-default", + "name": "Sign out of every device (global – default)", + "code": "```js\nconst { error } = await supabase.auth.signOut()\n```" + }, + { + "id": "sign-out-only-the-current-session-recommended-for-most-apps", + "name": "Sign out only the current session (recommended for most apps)", + "code": "```js\nconst { error } = await supabase.auth.signOut({ scope: 'local' })\n```" + }, + { + "id": "sign-out-of-all-other-sessions-keep-the-current-one", + "name": "Sign out of all other sessions, keep the current one", + "code": "```js\nconst { error } = await supabase.auth.signOut({ scope: 'others' })\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.signUp": { + "name": "@supabase/auth-js.GoTrueClient.signUp", + "params": [ + { + "name": "credentials", + "type": { + "type": "nameOnly", + "name": "SignUpWithPasswordCredentials" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + "[Circular]" + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "[Circular]" + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a new user.\n\nBe aware that if a user account exists in the system you may get back an\nerror message that attempts to hide this information from the user.\nThis method has support for PKCE via email signups. The PKCE flow cannot be used when autoconfirm is enabled.", + "text": "- By default, the user needs to verify their email address before logging in. To turn this off, disable **Confirm email** in [your project](/dashboard/project/_/auth/providers).\n- **Confirm email** determines if users need to confirm their email address after signing up.\n - If **Confirm email** is enabled, a `user` is returned but `session` is null.\n - If **Confirm email** is disabled, both a `user` and a `session` are returned.\n- When the user confirms their email address, they are redirected to the [`SITE_URL`](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls) by default. You can modify your `SITE_URL` or add additional redirect URLs in [your project](/dashboard/project/_/auth/url-configuration).\n- If signUp() is called for an existing confirmed user:\n - When both **Confirm email** and **Confirm phone** (even when phone provider is disabled) are enabled in [your project](/dashboard/project/_/auth/providers), an obfuscated/fake user object is returned.\n - When either **Confirm email** or **Confirm phone** (even when phone provider is disabled) is disabled, the error message, `User already registered` is returned.\n- To fetch the currently logged-in user, refer to [`getUser()`](/docs/reference/javascript/auth-getuser).", + "examples": [ + { + "id": "sign-up-with-an-email-and-password", + "name": "Sign up with an email and password", + "code": "```js\nconst { data, error } = await supabase.auth.signUp({\n email: 'example@email.com',\n password: 'example-password',\n})\n```", + "response": "```json\n// Some fields may be null if \"confirm email\" is enabled.\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {},\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\"\n },\n \"session\": {\n \"access_token\": \"\",\n \"token_type\": \"bearer\",\n \"expires_in\": 3600,\n \"expires_at\": 1700000000,\n \"refresh_token\": \"\",\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {},\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\"\n }\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "sign-up-with-a-phone-number-and-password-sms", + "name": "Sign up with a phone number and password (SMS)", + "code": "```js\nconst { data, error } = await supabase.auth.signUp({\n phone: '123456789',\n password: 'example-password',\n options: {\n channel: 'sms'\n }\n})\n```" + }, + { + "id": "sign-up-with-a-phone-number-and-password-whatsapp", + "name": "Sign up with a phone number and password (whatsapp)", + "code": "```js\nconst { data, error } = await supabase.auth.signUp({\n phone: '123456789',\n password: 'example-password',\n options: {\n channel: 'whatsapp'\n }\n})\n```", + "description": "The user will be sent a WhatsApp message which contains a OTP. By default, a given user can only request a OTP once every 60 seconds. Note that a user will need to have a valid WhatsApp account that is linked to Twilio in order to use this feature." + }, + { + "id": "sign-up-with-additional-user-metadata", + "name": "Sign up with additional user metadata", + "code": "```js\nconst { data, error } = await supabase.auth.signUp(\n {\n email: 'example@email.com',\n password: 'example-password',\n options: {\n data: {\n first_name: 'John',\n age: 27,\n }\n }\n }\n)\n```" + }, + { + "id": "sign-up-with-a-redirect-url", + "name": "Sign up with a redirect URL", + "code": "```js\nconst { data, error } = await supabase.auth.signUp(\n {\n email: 'example@email.com',\n password: 'example-password',\n options: {\n emailRedirectTo: 'https://example.com/welcome'\n }\n }\n)\n```", + "description": "- See [redirect URLs and wildcards](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls) to add additional redirect URLs to your project." + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.startAutoRefresh": { + "name": "@supabase/auth-js.GoTrueClient.startAutoRefresh", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "Starts an auto-refresh process in the background. The session is checked\nevery few seconds. Close to the time of expiration a process is started to\nrefresh the session. If refreshing fails it will be retried for as long as\nnecessary.\n\nIf you set the GoTrueClientOptions#autoRefreshToken you don't need\nto call this function, it will be called for you.\n\nOn browsers the refresh process works only when the tab/window is in the\nforeground to conserve resources as well as prevent race conditions and\nflooding auth with requests. If you call this method any managed\nvisibility change callback will be removed and you must manage visibility\nchanges on your own.\n\nOn non-browser platforms the refresh process works *continuously* in the\nbackground, which may not be desirable. You should hook into your\nplatform's foreground indication mechanism and call these methods\nappropriately to conserve resources.\n\n#stopAutoRefresh", + "text": "- Only useful in non-browser environments such as React Native or Electron.\n- The Supabase Auth library automatically starts and stops proactively refreshing the session when a tab is focused or not.\n- On non-browser platforms, such as mobile or desktop apps built with web technologies, the library is not able to effectively determine whether the application is _focused_ or not.\n- To give this hint to the application, you should be calling this method when the app is in focus and calling `supabase.auth.stopAutoRefresh()` when it's out of focus.", + "examples": [ + { + "id": "start-and-stop-auto-refresh-in-react-native", + "name": "Start and stop auto refresh in React Native", + "code": "```js\nimport { AppState } from 'react-native'\n\n// make sure you register this only once!\nAppState.addEventListener('change', (state) => {\n if (state === 'active') {\n supabase.auth.startAutoRefresh()\n } else {\n supabase.auth.stopAutoRefresh()\n }\n})\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.stopAutoRefresh": { + "name": "@supabase/auth-js.GoTrueClient.stopAutoRefresh", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "Stops an active auto refresh process running in the background (if any).\n\nIf you call this method any managed visibility change callback will be\nremoved and you must manage visibility changes on your own.\n\nSee #startAutoRefresh for more details.", + "text": "- Only useful in non-browser environments such as React Native or Electron.\n- The Supabase Auth library automatically starts and stops proactively refreshing the session when a tab is focused or not.\n- On non-browser platforms, such as mobile or desktop apps built with web technologies, the library is not able to effectively determine whether the application is _focused_ or not.\n- When your application goes in the background or out of focus, call this method to stop the proactive refreshing of the session.", + "examples": [ + { + "id": "start-and-stop-auto-refresh-in-react-native", + "name": "Start and stop auto refresh in React Native", + "code": "```js\nimport { AppState } from 'react-native'\n\n// make sure you register this only once!\nAppState.addEventListener('change', (state) => {\n if (state === 'active') {\n supabase.auth.startAutoRefresh()\n } else {\n supabase.auth.stopAutoRefresh()\n }\n})\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.unlinkIdentity": { + "name": "@supabase/auth-js.GoTrueClient.unlinkIdentity", + "params": [ + { + "name": "identity", + "type": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Unlinks an identity from a user by deleting it. The user will no longer be able to sign in with that identity once it's unlinked.", + "text": "- The **Enable Manual Linking** option must be enabled from your [project's authentication settings](/dashboard/project/_/auth/providers).\n- The user needs to be signed in to call `unlinkIdentity()`.\n- The user must have at least 2 identities in order to unlink an identity.\n- The identity to be unlinked must belong to the user.", + "examples": [ + { + "id": "unlink-an-identity", + "name": "Unlink an identity", + "code": "```js\n// retrieve all identities linked to a user\nconst identities = await supabase.auth.getUserIdentities()\n\n// find the google identity\nconst googleIdentity = identities.find(\n identity => identity.provider === 'google'\n)\n\n// unlink the google identity\nconst { error } = await supabase.auth.unlinkIdentity(googleIdentity)\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.updateUser": { + "name": "@supabase/auth-js.GoTrueClient.updateUser", + "params": [ + { + "name": "attributes", + "type": { + "type": "object", + "name": "UserAttributes", + "properties": [ + { + "name": "current_password", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The user's current password\n\nThis is only ever present when the user is resetting\ntheir password and GOTRUE_SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD is true." + } + }, + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "object" + }, + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.\n\nThe `data` should be a JSON object that includes user-specific info, such as their first and last name." + } + }, + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The user's email." + } + }, + { + "name": "nonce", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The nonce sent for reauthentication if the user's password is to be updated.\n\nCall reauthenticate() to obtain the nonce first." + } + }, + { + "name": "password", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The user's password." + } + }, + { + "name": "phone", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The user's phone." + } + } + ] + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "emailRedirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "UserResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Updates user data for a logged in user.", + "text": "- In order to use the `updateUser()` method, the user needs to be signed in first.\n- By default, email updates sends a confirmation link to both the user's current and new email.\nTo only send a confirmation link to the user's new email, disable **Secure email change** in your project's [email auth provider settings](/dashboard/project/_/auth/providers).", + "examples": [ + { + "id": "update-the-email-for-an-authenticated-user", + "name": "Update the email for an authenticated user", + "code": "```js\nconst { data, error } = await supabase.auth.updateUser({\n email: 'new@email.com'\n})\n```", + "description": "Sends a \"Confirm Email Change\" email to the new address. If **Secure Email Change** is enabled (default), confirmation is also required from the **old email** before the change is applied. To skip dual confirmation and apply the change after only the new email is verified, disable **Secure Email Change** in the [Email Auth Provider settings](/dashboard/project/_/auth/providers?provider=Email).", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"new_email\": \"new@email.com\",\n \"email_change_sent_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "update-the-phone-number-for-an-authenticated-user", + "name": "Update the phone number for an authenticated user", + "code": "```js\nconst { data, error } = await supabase.auth.updateUser({\n phone: '123456789'\n})\n```", + "description": "Sends a one-time password (OTP) to the new phone number." + }, + { + "id": "update-the-password-for-an-authenticated-user", + "name": "Update the password for an authenticated user", + "code": "```js\nconst { data, error } = await supabase.auth.updateUser({\n password: 'new password'\n})\n```" + }, + { + "id": "update-the-user-s-metadata", + "name": "Update the user's metadata", + "code": "```js\nconst { data, error } = await supabase.auth.updateUser({\n data: { hello: 'world' }\n})\n```", + "description": "Updates the user's custom metadata.\n\n**Note**: The `data` field maps to the `auth.users.raw_user_meta_data` column in your Supabase database. When calling `getUser()`, the data will be available as `user.user_metadata`." + }, + { + "id": "update-the-user-s-password-with-a-nonce", + "name": "Update the user's password with a nonce", + "code": "```js\nconst { data, error } = await supabase.auth.updateUser({\n password: 'new password',\n nonce: '123456'\n})\n```", + "description": "If **Secure password change** is enabled in your [project's email provider settings](/dashboard/project/_/auth/providers), updating the user's password would require a nonce if the user **hasn't recently signed in**. The nonce is sent to the user's email or phone number. A user is deemed recently signed in if the session was created in the last 24 hours." + } + ] + } + }, + "@supabase/auth-js.GoTrueClient.verifyOtp": { + "name": "@supabase/auth-js.GoTrueClient.verifyOtp", + "params": [ + { + "name": "params", + "type": { + "type": "union", + "name": "VerifyOtpParams", + "subTypes": [ + { + "type": "object", + "name": "VerifyMobileOtpParams", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "redirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "A URL to send the user to after they are confirmed." + } + } + ] + }, + "isOptional": true + }, + { + "name": "phone", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's phone number." + } + }, + { + "name": "token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The otp sent to the user's phone number." + } + }, + { + "name": "type", + "type": { + "type": "union", + "name": "MobileOtpType", + "subTypes": [ + { + "type": "literal", + "value": "sms" + }, + { + "type": "literal", + "value": "phone_change" + }, + null + ] + }, + "comment": { + "shortText": "The user's verification type." + } + } + ] + }, + { + "type": "object", + "name": "VerifyEmailOtpParams", + "properties": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's email address." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "redirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "A URL to send the user to after they are confirmed." + } + } + ] + }, + "isOptional": true + }, + { + "name": "token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The otp sent to the user's email address." + } + }, + { + "name": "type", + "type": { + "type": "union", + "name": "EmailOtpType", + "subTypes": [ + { + "type": "literal", + "value": "signup" + }, + { + "type": "literal", + "value": "invite" + }, + { + "type": "literal", + "value": "magiclink" + }, + { + "type": "literal", + "value": "recovery" + }, + { + "type": "literal", + "value": "email_change" + }, + { + "type": "literal", + "value": "email" + }, + null + ] + }, + "comment": { + "shortText": "The user's verification type." + } + } + ] + }, + { + "type": "object", + "name": "VerifyTokenHashParams", + "properties": [ + { + "name": "token_hash", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The token hash used in an email link" + } + }, + { + "name": "type", + "type": { + "type": "union", + "name": "EmailOtpType", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + }, + "comment": { + "shortText": "The user's verification type." + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + "[Circular]" + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "[Circular]" + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Log in a user given a User supplied OTP or TokenHash received through mobile or email.", + "text": "- The `verifyOtp` method takes in different verification types.\n- If a phone number is used, the type can either be:\n 1. `sms` – Used when verifying a one-time password (OTP) sent via SMS during sign-up or sign-in.\n 2. `phone_change` – Used when verifying an OTP sent to a new phone number during a phone number update process.\n- If an email address is used, the type can be one of the following (note: `signup` and `magiclink` types are deprecated):\n 1. `email` – Used when verifying an OTP sent to the user's email during sign-up or sign-in.\n 2. `recovery` – Used when verifying an OTP sent for account recovery, typically after a password reset request.\n 3. `invite` – Used when verifying an OTP sent as part of an invitation to join a project or organization.\n 4. `email_change` – Used when verifying an OTP sent to a new email address during an email update process.\n- The verification type used should be determined based on the corresponding auth method called before `verifyOtp` to sign up / sign-in a user.\n- The `TokenHash` is contained in the [email templates](/docs/guides/auth/auth-email-templates) and can be used to sign in. You may wish to use the hash for the PKCE flow for Server Side Auth. Read [the Password-based Auth guide](/docs/guides/auth/passwords) for more details.", + "examples": [ + { + "id": "verify-signup-one-time-password-otp", + "name": "Verify Signup One-Time Password (OTP)", + "code": "```js\nconst { data, error } = await supabase.auth.verifyOtp({ email, token, type: 'email'})\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"recovery_sent_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n },\n \"session\": {\n \"access_token\": \"\",\n \"token_type\": \"bearer\",\n \"expires_in\": 3600,\n \"expires_at\": 1700000000,\n \"refresh_token\": \"\",\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"recovery_sent_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n }\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "verify-sms-one-time-password-otp", + "name": "Verify SMS One-Time Password (OTP)", + "code": "```js\nconst { data, error } = await supabase.auth.verifyOtp({ phone, token, type: 'sms'})\n```" + }, + { + "id": "verify-email-auth-token-hash", + "name": "Verify Email Auth (Token Hash)", + "code": "```js\nconst { data, error } = await supabase.auth.verifyOtp({ token_hash: tokenHash, type: 'email'})\n```" + } + ] + } + }, + "@supabase/auth-js.NavigatorLockAcquireTimeoutError.constructor": { + "name": "@supabase/auth-js.NavigatorLockAcquireTimeoutError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "NavigatorLockAcquireTimeoutError" + } + } + }, + "@supabase/auth-js.AuthOAuthServerApi.approveAuthorization": { + "name": "@supabase/auth-js.AuthOAuthServerApi.approveAuthorization", + "params": [ + { + "name": "authorizationId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The authorization ID to approve" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "skipBrowserRedirect", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If false (default), automatically redirects the browser to the OAuth client. If true, returns the redirect_url without automatic redirect (useful for custom handling)." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Optional parameters" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthOAuthConsentResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "OAuthRedirect", + "type": "object", + "properties": [ + { + "name": "redirect_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Complete redirect URL with authorization code and state parameters (e.g., \"https://app.com/callback?code=xxx&state=yyy\")" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Approves an OAuth authorization request.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nAfter approval, the user's consent is stored and an authorization code is generated.\nThe response contains a complete redirect URL with the authorization code and state." + } + }, + "@supabase/auth-js.AuthOAuthServerApi.denyAuthorization": { + "name": "@supabase/auth-js.AuthOAuthServerApi.denyAuthorization", + "params": [ + { + "name": "authorizationId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The authorization ID to deny" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "skipBrowserRedirect", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If false (default), automatically redirects the browser to the OAuth client. If true, returns the redirect_url without automatic redirect (useful for custom handling)." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Optional parameters" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthOAuthConsentResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "OAuthRedirect", + "type": "object", + "properties": [ + { + "name": "redirect_url", + "type": "[Circular]", + "comment": { + "shortText": "Complete redirect URL with authorization code and state parameters (e.g., \"https://app.com/callback?code=xxx&state=yyy\")" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Denies an OAuth authorization request.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nAfter denial, the response contains a redirect URL with an OAuth error\n(access_denied) to inform the OAuth client that the user rejected the request." + } + }, + "@supabase/auth-js.AuthOAuthServerApi.getAuthorizationDetails": { + "name": "@supabase/auth-js.AuthOAuthServerApi.getAuthorizationDetails", + "params": [ + { + "name": "authorizationId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The authorization ID from the authorization request" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthOAuthAuthorizationDetailsResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "union", + "subTypes": [ + { + "name": "OAuthAuthorizationDetails", + "type": "object", + "properties": [ + { + "name": "authorization_id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The authorization ID used to approve or deny the request" + } + }, + { + "name": "client", + "type": { + "name": "OAuthAuthorizationClient", + "type": "object", + "properties": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Unique identifier for the OAuth client (UUID)" + } + }, + { + "name": "logo_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "URI of the OAuth client's logo" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Human-readable name of the OAuth client" + } + }, + { + "name": "uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "URI of the OAuth client's website" + } + } + ] + }, + "comment": { + "shortText": "OAuth client requesting authorization" + } + }, + { + "name": "redirect_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The OAuth client's registered redirect URI (base URI without query parameters)" + } + }, + { + "name": "scope", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Space-separated list of requested scopes (e.g., \"openid profile email\")" + } + }, + { + "name": "user", + "type": { + "type": "object", + "properties": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "User email" + } + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "User ID (UUID)" + } + } + ] + }, + "comment": { + "shortText": "User object associated with the authorization" + } + } + ] + }, + { + "name": "OAuthRedirect", + "type": "object", + "properties": [ + { + "name": "redirect_url", + "type": "[Circular]", + "comment": { + "shortText": "Complete redirect URL with authorization code and state parameters (e.g., \"https://app.com/callback?code=xxx&state=yyy\")" + } + } + ] + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Retrieves details about an OAuth authorization request.\nUsed to display consent information to the user.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nThis method returns one of two response types:\n- `OAuthAuthorizationDetails`: User needs to consent - show consent page with client info\n- `OAuthRedirect`: User already consented - redirect immediately to the OAuth client\n\nUse type narrowing to distinguish between the responses:\n```typescript\nif ('authorization_id' in data) {\n // Show consent page\n} else {\n // Redirect to data.redirect_url\n}\n```" + } + }, + "@supabase/auth-js.AuthOAuthServerApi.listGrants": { + "name": "@supabase/auth-js.AuthOAuthServerApi.listGrants", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthOAuthGrantsResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "array", + "elemType": { + "name": "OAuthGrant", + "type": "object", + "properties": [ + { + "name": "client", + "type": { + "name": "OAuthAuthorizationClient", + "type": "object", + "properties": [ + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier for the OAuth client (UUID)" + } + }, + { + "name": "logo_uri", + "type": "[Circular]", + "comment": { + "shortText": "URI of the OAuth client's logo" + } + }, + { + "name": "name", + "type": "[Circular]", + "comment": { + "shortText": "Human-readable name of the OAuth client" + } + }, + { + "name": "uri", + "type": "[Circular]", + "comment": { + "shortText": "URI of the OAuth client's website" + } + } + ] + }, + "comment": { + "shortText": "OAuth client information" + } + }, + { + "name": "granted_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Timestamp when the grant was created (ISO 8601 date-time)" + } + }, + { + "name": "scopes", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "comment": { + "shortText": "Array of scopes granted to this client" + } + } + ] + } + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists all OAuth grants that the authenticated user has authorized.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth." + } + }, + "@supabase/auth-js.AuthOAuthServerApi.revokeGrant": { + "name": "@supabase/auth-js.AuthOAuthServerApi.revokeGrant", + "params": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "clientId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The OAuth client identifier (UUID) to revoke access for" + } + } + ] + }, + "comment": { + "shortText": "Revocation options" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthOAuthRevokeGrantResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Revokes a user's OAuth grant for a specific client.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nRevocation marks consent as revoked, deletes active sessions for that OAuth client,\nand invalidates associated refresh tokens." + } + }, + "@supabase/auth-js.AuthPasskeyApi.delete": { + "name": "@supabase/auth-js.AuthPasskeyApi.delete", + "params": [ + { + "name": "params", + "type": { + "name": "PasskeyDeleteParams", + "type": "object", + "properties": [ + { + "name": "passkeyId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "UUID of the passkey to delete" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyDeleteResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Deletes a passkey for the currently signed-in user." + } + }, + "@supabase/auth-js.AuthPasskeyApi.list": { + "name": "@supabase/auth-js.AuthPasskeyApi.list", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyListResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "array", + "elemType": { + "name": "PasskeyListItem", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "friendly_name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "last_used_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + } + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists all passkeys registered for the currently signed-in user." + } + }, + "@supabase/auth-js.AuthPasskeyApi.startAuthentication": { + "name": "@supabase/auth-js.AuthPasskeyApi.startAuthentication", + "params": [ + { + "name": "params", + "type": { + "name": "StartPasskeyAuthenticationParams", + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyAuthenticationOptionsResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "PasskeyAuthenticationOptionsResponse", + "type": "object", + "properties": [ + { + "name": "challenge_id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "expires_at", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "options", + "type": { + "type": "nameOnly", + "name": "ServerCredentialRequestOptions" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Starts the passkey authentication ceremony. Fetches an authentication\nchallenge and credential request options from the server. Used as the\nfirst step of a two-step sign-in flow when the caller wants to handle\n`navigator.credentials.get()` themselves." + } + }, + "@supabase/auth-js.AuthPasskeyApi.startRegistration": { + "name": "@supabase/auth-js.AuthPasskeyApi.startRegistration", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyRegistrationOptionsResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "PasskeyRegistrationOptionsResponse", + "type": "object", + "properties": [ + { + "name": "challenge_id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "expires_at", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "options", + "type": { + "type": "nameOnly", + "name": "ServerCredentialCreationOptions" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Starts the passkey registration ceremony. Fetches a registration challenge\nand credential creation options from the server. Used as the first step of\na two-step registration flow when the caller wants to handle\n`navigator.credentials.create()` themselves." + } + }, + "@supabase/auth-js.AuthPasskeyApi.update": { + "name": "@supabase/auth-js.AuthPasskeyApi.update", + "params": [ + { + "name": "params", + "type": { + "name": "PasskeyUpdateParams", + "type": "object", + "properties": [ + { + "name": "friendlyName", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "New friendly name (max 120 chars)" + } + }, + { + "name": "passkeyId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "UUID of the passkey to update" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyUpdateResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "PasskeyListItem", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "last_used_at", + "type": "[Circular]", + "isOptional": true + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Updates a passkey's friendly name." + } + }, + "@supabase/auth-js.AuthPasskeyApi.verifyAuthentication": { + "name": "@supabase/auth-js.AuthPasskeyApi.verifyAuthentication", + "params": [ + { + "name": "params", + "type": { + "name": "VerifyPasskeyAuthenticationParams", + "type": "object", + "properties": [ + { + "name": "challengeId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Challenge ID from startAuthentication" + } + }, + { + "name": "credential", + "type": { + "type": "nameOnly", + "name": "ServerCredentialResponse" + }, + "comment": { + "shortText": "Serialized credential from navigator.credentials.get()" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyAuthenticationVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "Session", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + "[Circular]" + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "[Circular]" + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Verifies a passkey authentication credential against a previously issued\nchallenge. Used as the second step of a two-step sign-in flow." + } + }, + "@supabase/auth-js.AuthPasskeyApi.verifyRegistration": { + "name": "@supabase/auth-js.AuthPasskeyApi.verifyRegistration", + "params": [ + { + "name": "params", + "type": { + "name": "VerifyPasskeyRegistrationParams", + "type": "object", + "properties": [ + { + "name": "challengeId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Challenge ID from startRegistration" + } + }, + { + "name": "credential", + "type": { + "type": "nameOnly", + "name": "ServerCredentialResponse" + }, + "comment": { + "shortText": "Serialized credential from navigator.credentials.create()" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyRegistrationVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "PasskeyMetadata", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Verifies a passkey registration credential against a previously issued\nchallenge. Used as the second step of a two-step registration flow." + } + }, + "@supabase/auth-js.GoTrueAdminCustomProvidersApi.createProvider": { + "name": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.createProvider", + "params": [ + { + "name": "params", + "type": { + "name": "CreateCustomProviderParams", + "type": "object", + "properties": [ + { + "name": "acceptable_client_ids", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Additional client IDs accepted during token validation" + } + }, + { + "name": "attribute_mapping", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + "isOptional": true, + "comment": { + "shortText": "Mapping of provider attributes to Supabase user attributes" + } + }, + { + "name": "authorization_params", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Additional parameters sent with the authorization request" + } + }, + { + "name": "authorization_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 authorization URL" + } + }, + { + "name": "client_id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "OAuth client ID" + } + }, + { + "name": "client_secret", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "OAuth client secret (write-only, not returned in responses)" + } + }, + { + "name": "discovery_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OIDC discovery URL" + } + }, + { + "name": "email_optional", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether email is optional for this provider" + } + }, + { + "name": "enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether the provider is enabled" + } + }, + { + "name": "identifier", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Provider identifier (e.g. `custom:mycompany`)" + } + }, + { + "name": "issuer", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OIDC issuer URL" + } + }, + { + "name": "jwks_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "JWKS URI for token verification" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Human-readable name" + } + }, + { + "name": "pkce_enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether PKCE is enabled" + } + }, + { + "name": "provider_type", + "type": { + "type": "union", + "name": "CustomProviderType", + "subTypes": [ + { + "type": "literal", + "value": "oauth2" + }, + { + "type": "literal", + "value": "oidc" + } + ] + }, + "comment": { + "shortText": "Provider type" + } + }, + { + "name": "scopes", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "OAuth scopes requested during authorization" + } + }, + { + "name": "skip_nonce_check", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether to skip nonce check (OIDC)" + } + }, + { + "name": "token_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 token URL" + } + }, + { + "name": "userinfo_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 userinfo URL" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "CustomProviderResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "CustomOAuthProvider", + "type": "object", + "properties": [ + { + "name": "acceptable_client_ids", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Additional client IDs accepted during token validation" + } + }, + { + "name": "attribute_mapping", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + "isOptional": true, + "comment": { + "shortText": "Mapping of provider attributes to Supabase user attributes" + } + }, + { + "name": "authorization_params", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Additional parameters sent with the authorization request" + } + }, + { + "name": "authorization_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 authorization URL" + } + }, + { + "name": "client_id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "OAuth client ID" + } + }, + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Timestamp when the provider was created" + } + }, + { + "name": "discovery_document", + "type": { + "type": "union", + "subTypes": [ + { + "name": "OIDCDiscoveryDocument", + "type": "object", + "properties": [ + { + "name": "authorization_endpoint", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "URL of the authorization endpoint" + } + }, + { + "name": "issuer", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The issuer identifier" + } + }, + { + "name": "jwks_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "URL of the JSON Web Key Set" + } + }, + { + "name": "revocation_endpoint", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URL of the revocation endpoint" + } + }, + { + "name": "supported_id_token_signing_algs", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "List of supported ID token signing algorithms" + } + }, + { + "name": "supported_response_types", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "List of supported response types" + } + }, + { + "name": "supported_scopes", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "List of supported scopes" + } + }, + { + "name": "supported_subject_types", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "List of supported subject types" + } + }, + { + "name": "token_endpoint", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "URL of the token endpoint" + } + }, + { + "name": "userinfo_endpoint", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URL of the userinfo endpoint" + } + } + ] + }, + { + "type": "literal", + "value": null + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "OIDC discovery document (OIDC providers only)" + } + }, + { + "name": "discovery_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OIDC discovery URL" + } + }, + { + "name": "email_optional", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether email is optional for this provider" + } + }, + { + "name": "enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether the provider is enabled" + } + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Unique identifier (UUID)" + } + }, + { + "name": "identifier", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Provider identifier (e.g. `custom:mycompany`)" + } + }, + { + "name": "issuer", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OIDC issuer URL" + } + }, + { + "name": "jwks_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "JWKS URI for token verification" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Human-readable name" + } + }, + { + "name": "pkce_enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether PKCE is enabled" + } + }, + { + "name": "provider_type", + "type": { + "type": "union", + "name": "CustomProviderType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Provider type" + } + }, + { + "name": "scopes", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "OAuth scopes requested during authorization" + } + }, + { + "name": "skip_nonce_check", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether to skip nonce check (OIDC)" + } + }, + { + "name": "token_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 token URL" + } + }, + { + "name": "updated_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Timestamp when the provider was last updated" + } + }, + { + "name": "userinfo_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 userinfo URL" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a new custom OIDC/OAuth provider.\n\nFor OIDC providers, the server fetches and validates the OpenID Connect discovery document\nfrom the issuer's well-known endpoint (or the provided `discovery_url`) at creation time.\nThis may return a validation error (`error_code: \"validation_failed\"`) if the discovery\ndocument is unreachable, not valid JSON, missing required fields, or if the issuer\nin the document does not match the expected issuer.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/auth-js.GoTrueAdminCustomProvidersApi.deleteProvider": { + "name": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.deleteProvider", + "params": [ + { + "name": "identifier", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "nameOnly", + "name": "AuthError" + } + ] + } + } + ] + } + } + }, + "comment": { + "shortText": "Deletes a custom provider.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/auth-js.GoTrueAdminCustomProvidersApi.getProvider": { + "name": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.getProvider", + "params": [ + { + "name": "identifier", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "CustomProviderResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "CustomOAuthProvider", + "type": "object", + "properties": [ + { + "name": "acceptable_client_ids", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Additional client IDs accepted during token validation" + } + }, + { + "name": "attribute_mapping", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Mapping of provider attributes to Supabase user attributes" + } + }, + { + "name": "authorization_params", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Additional parameters sent with the authorization request" + } + }, + { + "name": "authorization_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 authorization URL" + } + }, + { + "name": "client_id", + "type": "[Circular]", + "comment": { + "shortText": "OAuth client ID" + } + }, + { + "name": "created_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the provider was created" + } + }, + { + "name": "discovery_document", + "type": { + "type": "union", + "subTypes": [ + { + "name": "OIDCDiscoveryDocument", + "type": "object", + "properties": [ + { + "name": "authorization_endpoint", + "type": "[Circular]", + "comment": { + "shortText": "URL of the authorization endpoint" + } + }, + { + "name": "issuer", + "type": "[Circular]", + "comment": { + "shortText": "The issuer identifier" + } + }, + { + "name": "jwks_uri", + "type": "[Circular]", + "comment": { + "shortText": "URL of the JSON Web Key Set" + } + }, + { + "name": "revocation_endpoint", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URL of the revocation endpoint" + } + }, + { + "name": "supported_id_token_signing_algs", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported ID token signing algorithms" + } + }, + { + "name": "supported_response_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported response types" + } + }, + { + "name": "supported_scopes", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported scopes" + } + }, + { + "name": "supported_subject_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported subject types" + } + }, + { + "name": "token_endpoint", + "type": "[Circular]", + "comment": { + "shortText": "URL of the token endpoint" + } + }, + { + "name": "userinfo_endpoint", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URL of the userinfo endpoint" + } + } + ] + }, + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "OIDC discovery document (OIDC providers only)" + } + }, + { + "name": "discovery_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OIDC discovery URL" + } + }, + { + "name": "email_optional", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether email is optional for this provider" + } + }, + { + "name": "enabled", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether the provider is enabled" + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier (UUID)" + } + }, + { + "name": "identifier", + "type": "[Circular]", + "comment": { + "shortText": "Provider identifier (e.g. `custom:mycompany`)" + } + }, + { + "name": "issuer", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OIDC issuer URL" + } + }, + { + "name": "jwks_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "JWKS URI for token verification" + } + }, + { + "name": "name", + "type": "[Circular]", + "comment": { + "shortText": "Human-readable name" + } + }, + { + "name": "pkce_enabled", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether PKCE is enabled" + } + }, + { + "name": "provider_type", + "type": { + "type": "union", + "name": "CustomProviderType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Provider type" + } + }, + { + "name": "scopes", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth scopes requested during authorization" + } + }, + { + "name": "skip_nonce_check", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether to skip nonce check (OIDC)" + } + }, + { + "name": "token_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 token URL" + } + }, + { + "name": "updated_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the provider was last updated" + } + }, + { + "name": "userinfo_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 userinfo URL" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Gets details of a specific custom provider by identifier.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/auth-js.GoTrueAdminCustomProvidersApi.listProviders": { + "name": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.listProviders", + "params": [ + { + "name": "params", + "type": { + "name": "ListCustomProvidersParams", + "type": "object", + "properties": [ + { + "name": "type", + "type": { + "type": "union", + "name": "CustomProviderType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "Filter by provider type" + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "CustomProviderListResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "providers", + "type": { + "type": "array", + "elemType": { + "name": "CustomOAuthProvider", + "type": "object", + "properties": [ + { + "name": "acceptable_client_ids", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Additional client IDs accepted during token validation" + } + }, + { + "name": "attribute_mapping", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Mapping of provider attributes to Supabase user attributes" + } + }, + { + "name": "authorization_params", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Additional parameters sent with the authorization request" + } + }, + { + "name": "authorization_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 authorization URL" + } + }, + { + "name": "client_id", + "type": "[Circular]", + "comment": { + "shortText": "OAuth client ID" + } + }, + { + "name": "created_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the provider was created" + } + }, + { + "name": "discovery_document", + "type": { + "type": "union", + "subTypes": [ + { + "name": "OIDCDiscoveryDocument", + "type": "object", + "properties": [ + { + "name": "authorization_endpoint", + "type": "[Circular]", + "comment": { + "shortText": "URL of the authorization endpoint" + } + }, + { + "name": "issuer", + "type": "[Circular]", + "comment": { + "shortText": "The issuer identifier" + } + }, + { + "name": "jwks_uri", + "type": "[Circular]", + "comment": { + "shortText": "URL of the JSON Web Key Set" + } + }, + { + "name": "revocation_endpoint", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URL of the revocation endpoint" + } + }, + { + "name": "supported_id_token_signing_algs", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported ID token signing algorithms" + } + }, + { + "name": "supported_response_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported response types" + } + }, + { + "name": "supported_scopes", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported scopes" + } + }, + { + "name": "supported_subject_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported subject types" + } + }, + { + "name": "token_endpoint", + "type": "[Circular]", + "comment": { + "shortText": "URL of the token endpoint" + } + }, + { + "name": "userinfo_endpoint", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URL of the userinfo endpoint" + } + } + ] + }, + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "OIDC discovery document (OIDC providers only)" + } + }, + { + "name": "discovery_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OIDC discovery URL" + } + }, + { + "name": "email_optional", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether email is optional for this provider" + } + }, + { + "name": "enabled", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether the provider is enabled" + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier (UUID)" + } + }, + { + "name": "identifier", + "type": "[Circular]", + "comment": { + "shortText": "Provider identifier (e.g. `custom:mycompany`)" + } + }, + { + "name": "issuer", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OIDC issuer URL" + } + }, + { + "name": "jwks_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "JWKS URI for token verification" + } + }, + { + "name": "name", + "type": "[Circular]", + "comment": { + "shortText": "Human-readable name" + } + }, + { + "name": "pkce_enabled", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether PKCE is enabled" + } + }, + { + "name": "provider_type", + "type": { + "type": "union", + "name": "CustomProviderType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Provider type" + } + }, + { + "name": "scopes", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth scopes requested during authorization" + } + }, + { + "name": "skip_nonce_check", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether to skip nonce check (OIDC)" + } + }, + { + "name": "token_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 token URL" + } + }, + { + "name": "updated_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the provider was last updated" + } + }, + { + "name": "userinfo_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 userinfo URL" + } + } + ] + } + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "providers" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists all custom providers with optional type filter.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/auth-js.GoTrueAdminCustomProvidersApi.updateProvider": { + "name": "@supabase/auth-js.GoTrueAdminCustomProvidersApi.updateProvider", + "params": [ + { + "name": "identifier", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "params", + "type": { + "name": "UpdateCustomProviderParams", + "type": "object", + "properties": [ + { + "name": "acceptable_client_ids", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Additional client IDs accepted during token validation" + } + }, + { + "name": "attribute_mapping", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + "isOptional": true, + "comment": { + "shortText": "Mapping of provider attributes to Supabase user attributes" + } + }, + { + "name": "authorization_params", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Additional parameters sent with the authorization request" + } + }, + { + "name": "authorization_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 authorization URL" + } + }, + { + "name": "client_id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth client ID" + } + }, + { + "name": "client_secret", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth client secret (write-only, not returned in responses)" + } + }, + { + "name": "discovery_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OIDC discovery URL" + } + }, + { + "name": "email_optional", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether email is optional for this provider" + } + }, + { + "name": "enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether the provider is enabled" + } + }, + { + "name": "issuer", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OIDC issuer URL" + } + }, + { + "name": "jwks_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "JWKS URI for token verification" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Human-readable name" + } + }, + { + "name": "pkce_enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether PKCE is enabled" + } + }, + { + "name": "scopes", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "OAuth scopes requested during authorization" + } + }, + { + "name": "skip_nonce_check", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether to skip nonce check (OIDC)" + } + }, + { + "name": "token_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 token URL" + } + }, + { + "name": "userinfo_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 userinfo URL" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "CustomProviderResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "CustomOAuthProvider", + "type": "object", + "properties": [ + { + "name": "acceptable_client_ids", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Additional client IDs accepted during token validation" + } + }, + { + "name": "attribute_mapping", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Mapping of provider attributes to Supabase user attributes" + } + }, + { + "name": "authorization_params", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Additional parameters sent with the authorization request" + } + }, + { + "name": "authorization_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 authorization URL" + } + }, + { + "name": "client_id", + "type": "[Circular]", + "comment": { + "shortText": "OAuth client ID" + } + }, + { + "name": "created_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the provider was created" + } + }, + { + "name": "discovery_document", + "type": { + "type": "union", + "subTypes": [ + { + "name": "OIDCDiscoveryDocument", + "type": "object", + "properties": [ + { + "name": "authorization_endpoint", + "type": "[Circular]", + "comment": { + "shortText": "URL of the authorization endpoint" + } + }, + { + "name": "issuer", + "type": "[Circular]", + "comment": { + "shortText": "The issuer identifier" + } + }, + { + "name": "jwks_uri", + "type": "[Circular]", + "comment": { + "shortText": "URL of the JSON Web Key Set" + } + }, + { + "name": "revocation_endpoint", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URL of the revocation endpoint" + } + }, + { + "name": "supported_id_token_signing_algs", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported ID token signing algorithms" + } + }, + { + "name": "supported_response_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported response types" + } + }, + { + "name": "supported_scopes", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported scopes" + } + }, + { + "name": "supported_subject_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported subject types" + } + }, + { + "name": "token_endpoint", + "type": "[Circular]", + "comment": { + "shortText": "URL of the token endpoint" + } + }, + { + "name": "userinfo_endpoint", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URL of the userinfo endpoint" + } + } + ] + }, + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "OIDC discovery document (OIDC providers only)" + } + }, + { + "name": "discovery_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OIDC discovery URL" + } + }, + { + "name": "email_optional", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether email is optional for this provider" + } + }, + { + "name": "enabled", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether the provider is enabled" + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier (UUID)" + } + }, + { + "name": "identifier", + "type": "[Circular]", + "comment": { + "shortText": "Provider identifier (e.g. `custom:mycompany`)" + } + }, + { + "name": "issuer", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OIDC issuer URL" + } + }, + { + "name": "jwks_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "JWKS URI for token verification" + } + }, + { + "name": "name", + "type": "[Circular]", + "comment": { + "shortText": "Human-readable name" + } + }, + { + "name": "pkce_enabled", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether PKCE is enabled" + } + }, + { + "name": "provider_type", + "type": { + "type": "union", + "name": "CustomProviderType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Provider type" + } + }, + { + "name": "scopes", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth scopes requested during authorization" + } + }, + { + "name": "skip_nonce_check", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether to skip nonce check (OIDC)" + } + }, + { + "name": "token_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 token URL" + } + }, + { + "name": "updated_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the provider was last updated" + } + }, + { + "name": "userinfo_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 userinfo URL" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Updates an existing custom provider.\n\nWhen `issuer` or `discovery_url` is changed on an OIDC provider, the server re-fetches and\nvalidates the discovery document before persisting. This may return a validation error\n(`error_code: \"validation_failed\"`) if the discovery document is unreachable, invalid, or\nthe issuer does not match.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/auth-js.GoTrueAdminMFAApi.deleteFactor": { + "name": "@supabase/auth-js.GoTrueAdminMFAApi.deleteFactor", + "params": [ + { + "name": "params", + "type": { + "name": "AuthMFAAdminDeleteFactorParams", + "type": "object", + "properties": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "ID of the MFA factor to delete." + } + }, + { + "name": "userId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "ID of the user whose factor is being deleted." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAAdminDeleteFactorResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "ID of the factor that was successfully deleted." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Deletes a factor on a user. This will log the user out of all active\nsessions if the deleted factor was verified.", + "examples": [ + { + "id": "delete-a-factor-for-a-user", + "name": "Delete a factor for a user", + "code": "```js\nconst { data, error } = await supabase.auth.admin.mfa.deleteFactor({\n id: '34e770dd-9ff9-416c-87fa-43b31d7ef225',\n userId: 'a89baba7-b1b7-440f-b4bb-91026967f66b',\n})\n```", + "response": "```json\n{\n data: {\n id: '34e770dd-9ff9-416c-87fa-43b31d7ef225'\n },\n error: null\n}\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueAdminMFAApi.listFactors": { + "name": "@supabase/auth-js.GoTrueAdminMFAApi.listFactors", + "params": [ + { + "name": "params", + "type": { + "name": "AuthMFAAdminListFactorsParams", + "type": "object", + "properties": [ + { + "name": "userId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "ID of the user." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAAdminListFactorsResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "nameOnly", + "name": "Type" + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "nameOnly", + "name": "Status" + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + }, + "comment": { + "shortText": "All factors attached to the user." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists all factors associated to a user.", + "examples": [ + { + "id": "list-all-factors-for-a-user", + "name": "List all factors for a user", + "code": "```js\nconst { data, error } = await supabase.auth.admin.mfa.listFactors()\n```", + "response": "```json\n{\n data: {\n factors: Factor[\n {\n id: '',\n friendly_name: 'Auth App Factor',\n factor_type: 'totp',\n status: 'verified',\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z'\n }\n ]\n },\n error: null\n}\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueAdminOAuthApi.createClient": { + "name": "@supabase/auth-js.GoTrueAdminOAuthApi.createClient", + "params": [ + { + "name": "params", + "type": { + "name": "CreateOAuthClientParams", + "type": "object", + "properties": [ + { + "name": "client_name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Human-readable name of the OAuth client" + } + }, + { + "name": "client_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client" + } + }, + { + "name": "grant_types", + "type": { + "type": "array", + "elemType": { + "type": "union", + "name": "OAuthClientGrantType", + "subTypes": [ + { + "type": "literal", + "value": "authorization_code" + }, + { + "type": "literal", + "value": "refresh_token" + }, + null + ] + } + }, + "isOptional": true, + "comment": { + "shortText": "Array of allowed grant types (optional, defaults to authorization_code and refresh_token)" + } + }, + { + "name": "redirect_uris", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "comment": { + "shortText": "Array of allowed redirect URIs" + } + }, + { + "name": "response_types", + "type": { + "type": "array", + "elemType": { + "type": "literal", + "value": "code", + "name": "OAuthClientResponseType" + } + }, + "isOptional": true, + "comment": { + "shortText": "Array of allowed response types (optional, defaults to code)" + } + }, + { + "name": "scope", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Scope of the OAuth client" + } + }, + { + "name": "token_endpoint_auth_method", + "type": { + "type": "union", + "name": "OAuthClientTokenEndpointAuthMethod", + "subTypes": [ + { + "type": "literal", + "value": "none" + }, + { + "type": "literal", + "value": "client_secret_basic" + }, + { + "type": "literal", + "value": "client_secret_post" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Token endpoint authentication method (defaults to server default if not specified)" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "OAuthClientResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "OAuthClient", + "type": "object", + "properties": [ + { + "name": "client_id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Unique identifier for the OAuth client" + } + }, + { + "name": "client_name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Human-readable name of the OAuth client" + } + }, + { + "name": "client_secret", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Client secret (only returned on registration and regeneration)" + } + }, + { + "name": "client_type", + "type": { + "type": "union", + "name": "OAuthClientType", + "subTypes": [ + { + "type": "literal", + "value": "public" + }, + { + "type": "literal", + "value": "confidential" + } + ] + }, + "comment": { + "shortText": "Type of OAuth client" + } + }, + { + "name": "client_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client" + } + }, + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Timestamp when the client was created" + } + }, + { + "name": "grant_types", + "type": { + "type": "array", + "elemType": { + "type": "union", + "name": "OAuthClientGrantType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + } + }, + "comment": { + "shortText": "Array of allowed grant types" + } + }, + { + "name": "logo_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client's logo" + } + }, + { + "name": "redirect_uris", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "comment": { + "shortText": "Array of allowed redirect URIs" + } + }, + { + "name": "registration_type", + "type": { + "type": "union", + "name": "OAuthClientRegistrationType", + "subTypes": [ + { + "type": "literal", + "value": "dynamic" + }, + { + "type": "literal", + "value": "manual" + } + ] + }, + "comment": { + "shortText": "Registration type of the client" + } + }, + { + "name": "response_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "comment": { + "shortText": "Array of allowed response types" + } + }, + { + "name": "scope", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Scope of the OAuth client" + } + }, + { + "name": "token_endpoint_auth_method", + "type": { + "type": "union", + "name": "OAuthClientTokenEndpointAuthMethod", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Token endpoint authentication method" + } + }, + { + "name": "updated_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Timestamp when the client was last updated" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a new OAuth client.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/auth-js.GoTrueAdminOAuthApi.deleteClient": { + "name": "@supabase/auth-js.GoTrueAdminOAuthApi.deleteClient", + "params": [ + { + "name": "clientId", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "nameOnly", + "name": "AuthError" + } + ] + } + } + ] + } + } + }, + "comment": { + "shortText": "Deletes an OAuth client.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/auth-js.GoTrueAdminOAuthApi.getClient": { + "name": "@supabase/auth-js.GoTrueAdminOAuthApi.getClient", + "params": [ + { + "name": "clientId", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "OAuthClientResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "OAuthClient", + "type": "object", + "properties": [ + { + "name": "client_id", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier for the OAuth client" + } + }, + { + "name": "client_name", + "type": "[Circular]", + "comment": { + "shortText": "Human-readable name of the OAuth client" + } + }, + { + "name": "client_secret", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Client secret (only returned on registration and regeneration)" + } + }, + { + "name": "client_type", + "type": { + "type": "union", + "name": "OAuthClientType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of OAuth client" + } + }, + { + "name": "client_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client" + } + }, + { + "name": "created_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the client was created" + } + }, + { + "name": "grant_types", + "type": { + "type": "array", + "elemType": { + "type": "union", + "name": "OAuthClientGrantType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + } + }, + "comment": { + "shortText": "Array of allowed grant types" + } + }, + { + "name": "logo_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client's logo" + } + }, + { + "name": "redirect_uris", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "comment": { + "shortText": "Array of allowed redirect URIs" + } + }, + { + "name": "registration_type", + "type": { + "type": "union", + "name": "OAuthClientRegistrationType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Registration type of the client" + } + }, + { + "name": "response_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "comment": { + "shortText": "Array of allowed response types" + } + }, + { + "name": "scope", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Scope of the OAuth client" + } + }, + { + "name": "token_endpoint_auth_method", + "type": { + "type": "union", + "name": "OAuthClientTokenEndpointAuthMethod", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Token endpoint authentication method" + } + }, + { + "name": "updated_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the client was last updated" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Gets details of a specific OAuth client.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/auth-js.GoTrueAdminOAuthApi.listClients": { + "name": "@supabase/auth-js.GoTrueAdminOAuthApi.listClients", + "params": [ + { + "name": "params", + "type": { + "name": "PageParams", + "type": "object", + "properties": [ + { + "name": "page", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The page number" + } + }, + { + "name": "perPage", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Number of items returned per page" + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "OAuthClientListResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "clients" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists all OAuth clients with optional pagination.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/auth-js.GoTrueAdminOAuthApi.regenerateClientSecret": { + "name": "@supabase/auth-js.GoTrueAdminOAuthApi.regenerateClientSecret", + "params": [ + { + "name": "clientId", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "OAuthClientResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "OAuthClient", + "type": "object", + "properties": [ + { + "name": "client_id", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier for the OAuth client" + } + }, + { + "name": "client_name", + "type": "[Circular]", + "comment": { + "shortText": "Human-readable name of the OAuth client" + } + }, + { + "name": "client_secret", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Client secret (only returned on registration and regeneration)" + } + }, + { + "name": "client_type", + "type": { + "type": "union", + "name": "OAuthClientType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of OAuth client" + } + }, + { + "name": "client_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client" + } + }, + { + "name": "created_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the client was created" + } + }, + { + "name": "grant_types", + "type": { + "type": "array", + "elemType": { + "type": "union", + "name": "OAuthClientGrantType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + } + }, + "comment": { + "shortText": "Array of allowed grant types" + } + }, + { + "name": "logo_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client's logo" + } + }, + { + "name": "redirect_uris", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "comment": { + "shortText": "Array of allowed redirect URIs" + } + }, + { + "name": "registration_type", + "type": { + "type": "union", + "name": "OAuthClientRegistrationType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Registration type of the client" + } + }, + { + "name": "response_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "comment": { + "shortText": "Array of allowed response types" + } + }, + { + "name": "scope", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Scope of the OAuth client" + } + }, + { + "name": "token_endpoint_auth_method", + "type": { + "type": "union", + "name": "OAuthClientTokenEndpointAuthMethod", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Token endpoint authentication method" + } + }, + { + "name": "updated_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the client was last updated" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Regenerates the secret for an OAuth client.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/auth-js.GoTrueAdminOAuthApi.updateClient": { + "name": "@supabase/auth-js.GoTrueAdminOAuthApi.updateClient", + "params": [ + { + "name": "clientId", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "params", + "type": { + "name": "UpdateOAuthClientParams", + "type": "object", + "properties": [ + { + "name": "client_name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Human-readable name of the OAuth client" + } + }, + { + "name": "client_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client" + } + }, + { + "name": "grant_types", + "type": { + "type": "array", + "elemType": { + "type": "union", + "name": "OAuthClientGrantType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + } + }, + "isOptional": true, + "comment": { + "shortText": "Array of allowed grant types" + } + }, + { + "name": "logo_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client's logo" + } + }, + { + "name": "redirect_uris", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Array of allowed redirect URIs" + } + }, + { + "name": "token_endpoint_auth_method", + "type": { + "type": "union", + "name": "OAuthClientTokenEndpointAuthMethod", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "Token endpoint authentication method" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "OAuthClientResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "OAuthClient", + "type": "object", + "properties": [ + { + "name": "client_id", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier for the OAuth client" + } + }, + { + "name": "client_name", + "type": "[Circular]", + "comment": { + "shortText": "Human-readable name of the OAuth client" + } + }, + { + "name": "client_secret", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Client secret (only returned on registration and regeneration)" + } + }, + { + "name": "client_type", + "type": { + "type": "union", + "name": "OAuthClientType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of OAuth client" + } + }, + { + "name": "client_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client" + } + }, + { + "name": "created_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the client was created" + } + }, + { + "name": "grant_types", + "type": { + "type": "array", + "elemType": { + "type": "union", + "name": "OAuthClientGrantType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + } + }, + "comment": { + "shortText": "Array of allowed grant types" + } + }, + { + "name": "logo_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client's logo" + } + }, + { + "name": "redirect_uris", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "comment": { + "shortText": "Array of allowed redirect URIs" + } + }, + { + "name": "registration_type", + "type": { + "type": "union", + "name": "OAuthClientRegistrationType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Registration type of the client" + } + }, + { + "name": "response_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "comment": { + "shortText": "Array of allowed response types" + } + }, + { + "name": "scope", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Scope of the OAuth client" + } + }, + { + "name": "token_endpoint_auth_method", + "type": { + "type": "union", + "name": "OAuthClientTokenEndpointAuthMethod", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Token endpoint authentication method" + } + }, + { + "name": "updated_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the client was last updated" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Updates an existing OAuth client.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/auth-js.GoTrueAdminPasskeyApi.deletePasskey": { + "name": "@supabase/auth-js.GoTrueAdminPasskeyApi.deletePasskey", + "params": [ + { + "name": "params", + "type": { + "name": "AuthPasskeyAdminDeleteParams", + "type": "object", + "properties": [ + { + "name": "passkeyId", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "userId", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyDeleteResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Deletes a specific passkey for a specific user.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/auth-js.GoTrueAdminPasskeyApi.listPasskeys": { + "name": "@supabase/auth-js.GoTrueAdminPasskeyApi.listPasskeys", + "params": [ + { + "name": "params", + "type": { + "name": "AuthPasskeyAdminListParams", + "type": "object", + "properties": [ + { + "name": "userId", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyListResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "array", + "elemType": { + "name": "PasskeyListItem", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "last_used_at", + "type": "[Circular]", + "isOptional": true + } + ] + } + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists all passkeys registered for a specific user.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/auth-js.GoTrueMFAApi.challenge": { + "name": "@supabase/auth-js.GoTrueMFAApi.challenge", + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAChallengeParamsBase" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "nameOnly", + "name": "AuthMFAChallengeResponseBase" + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Prepares a challenge used to verify that a user has access to a MFA\nfactor.", + "text": "- An [enrolled factor](/docs/reference/javascript/auth-mfa-enroll) is required before creating a challenge.\n- To verify a challenge, see [`mfa.verify()`](/docs/reference/javascript/auth-mfa-verify).\n- A phone factor sends a code to the user upon challenge. The channel defaults to `sms` unless otherwise specified.", + "examples": [ + { + "id": "create-a-challenge-for-a-factor", + "name": "Create a challenge for a factor", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.challenge({\n factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225'\n})\n```", + "response": "```json\n{\n data: {\n id: '',\n type: 'totp',\n expires_at: 1700000000\n },\n error: null\n}\n```" + }, + { + "id": "create-a-challenge-for-a-phone-factor", + "name": "Create a challenge for a phone factor", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.challenge({\n factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',\n})\n```", + "response": "```json\n{\n data: {\n id: '',\n type: 'phone',\n expires_at: 1700000000\n },\n error: null\n}\n```" + }, + { + "id": "create-a-challenge-for-a-phone-factor-whatsapp", + "name": "Create a challenge for a phone factor (WhatsApp)", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.challenge({\n factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',\n channel: 'whatsapp',\n})\n```", + "response": "```json\n{\n data: {\n id: '',\n expires_at: 1700000000\n },\n error: null\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAChallengePhoneParams" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "nameOnly", + "name": "AuthMFAChallengeResponseBase" + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + } + ] + } + } + } + }, + { + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAChallengeWebauthnParams" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + } + ] + } + } + } + }, + { + "params": [ + { + "name": "params", + "type": { + "type": "union", + "name": "MFAChallengeParams", + "subTypes": [ + { + "type": "nameOnly", + "name": "MFAChallengeTOTPParams" + }, + { + "type": "nameOnly", + "name": "MFAChallengePhoneParams" + }, + { + "type": "nameOnly", + "name": "MFAChallengeWebauthnParams" + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAChallengeResponse", + "subTypes": [ + { + "type": "union", + "name": "AuthMFAChallengeTOTPResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + }, + { + "type": "union", + "name": "AuthMFAChallengePhoneResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + }, + { + "type": "union", + "name": "AuthMFAChallengeWebauthnResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + ] + } + } + } + } + ] + }, + "@supabase/auth-js.GoTrueMFAApi.challengeAndVerify": { + "name": "@supabase/auth-js.GoTrueMFAApi.challengeAndVerify", + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAChallengeAndVerifyTOTPParams" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "AuthMFAVerifyResponseData", + "type": "object", + "properties": [ + { + "name": "access_token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "New access token (JWT) after successful verification." + } + }, + { + "name": "expires_in", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "Number of seconds in which the access token will expire." + } + }, + { + "name": "refresh_token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Refresh token you can use to obtain new access tokens when expired." + } + }, + { + "name": "token_type", + "type": { + "type": "literal", + "value": "bearer" + }, + "comment": { + "shortText": "Type of token, always `bearer`." + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "Updated user profile." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Helper method which creates a challenge and immediately uses the given code to verify against it thereafter. The verification code is\nprovided by the user by entering a code seen in their authenticator app.", + "text": "- Intended for use with only TOTP factors.\n- An [enrolled factor](/docs/reference/javascript/auth-mfa-enroll) is required before invoking `challengeAndVerify()`.\n- Executes [`mfa.challenge()`](/docs/reference/javascript/auth-mfa-challenge) and [`mfa.verify()`](/docs/reference/javascript/auth-mfa-verify) in a single step.", + "examples": [ + { + "id": "create-and-verify-a-challenge-for-a-factor", + "name": "Create and verify a challenge for a factor", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.challengeAndVerify({\n factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',\n code: '123456'\n})\n```", + "response": "```json\n{\n data: {\n access_token: '',\n token_type: 'Bearer',\n expires_in: 3600,\n refresh_token: '',\n user: {\n id: '11111111-1111-1111-1111-111111111111',\n aud: 'authenticated',\n role: 'authenticated',\n email: 'example@email.com',\n email_confirmed_at: '2024-01-01T00:00:00Z',\n phone: '',\n confirmation_sent_at: '2024-01-01T00:00:00Z',\n confirmed_at: '2024-01-01T00:00:00Z',\n last_sign_in_at: '2024-01-01T00:00:00Z',\n app_metadata: {\n provider: 'email',\n providers: [\n \"email\",\n ]\n },\n user_metadata: {},\n identities: [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": true,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"email@example.com\"\n },\n ],\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n is_anonymous: false,\n factors: [\n \"id\": '',\n \"friendly_name\": 'Important Auth App',\n \"factor_type\": 'totp',\n \"status\": 'verified',\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\"\n ]\n }\n }\n error: null\n}\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueMFAApi.enroll": { + "name": "@supabase/auth-js.GoTrueMFAApi.enroll", + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAEnrollTOTPParams" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAEnrollTOTPResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Starts the enrollment process for a new Multi-Factor Authentication (MFA)\nfactor. This method creates a new `unverified` factor.\nTo verify a factor, present the QR code or secret to the user and ask them to add it to their\nauthenticator app.\nThe user has to enter the code from their authenticator app to verify it.\n\nUpon verifying a factor, all other sessions are logged out and the current session's authenticator level is promoted to `aal2`.", + "text": "- Use `totp` or `phone` as the `factorType` and use the returned `id` to create a challenge.\n- To create a challenge, see [`mfa.challenge()`](/docs/reference/javascript/auth-mfa-challenge).\n- To verify a challenge, see [`mfa.verify()`](/docs/reference/javascript/auth-mfa-verify).\n- To create and verify a TOTP challenge in a single step, see [`mfa.challengeAndVerify()`](/docs/reference/javascript/auth-mfa-challengeandverify).\n- To generate a QR code for the `totp` secret in Next.js, you can do the following:\n```html\n{data.totp.uri}\n```\n- The `challenge` and `verify` steps are separated when using Phone factors as the user will need time to receive and input the code obtained from the SMS in challenge.", + "examples": [ + { + "id": "enroll-a-time-based-one-time-password-totp-factor", + "name": "Enroll a time-based, one-time password (TOTP) factor", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.enroll({\n factorType: 'totp',\n friendlyName: 'your_friendly_name'\n})\n\n// Use the id to create a challenge.\n// The challenge can be verified by entering the code generated from the authenticator app.\n// The code will be generated upon scanning the qr_code or entering the secret into the authenticator app.\nconst { id, type, totp: { qr_code, secret, uri }, friendly_name } = data\nconst challenge = await supabase.auth.mfa.challenge({ factorId: id });\n```", + "response": "```json\n{\n data: {\n id: '',\n type: 'totp'\n totp: {\n qr_code: '',\n secret: '',\n uri: '',\n }\n friendly_name?: 'Important app'\n },\n error: null\n}\n```" + }, + { + "id": "enroll-a-phone-factor", + "name": "Enroll a Phone Factor", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.enroll({\n factorType: 'phone',\n friendlyName: 'your_friendly_name',\n phone: '+12345678',\n})\n\n// Use the id to create a challenge and send an SMS with a code to the user.\nconst { id, type, friendly_name, phone } = data\n\nconst challenge = await supabase.auth.mfa.challenge({ factorId: id });\n```", + "response": "```json\n{\n data: {\n id: '',\n type: 'phone',\n friendly_name?: 'Important app',\n phone: '+5787123456'\n },\n error: null\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAEnrollPhoneParams" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAEnrollPhoneResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + } + }, + { + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAEnrollParamsBase" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAEnrollWebauthnResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + } + }, + { + "params": [ + { + "name": "params", + "type": { + "type": "union", + "name": "MFAEnrollParams", + "subTypes": [ + { + "type": "nameOnly", + "name": "MFAEnrollTOTPParams" + }, + { + "type": "nameOnly", + "name": "MFAEnrollPhoneParams" + }, + { + "type": "nameOnly", + "name": "MFAEnrollWebauthnParams" + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAEnrollResponse", + "subTypes": [ + { + "type": "union", + "name": "AuthMFAEnrollTOTPResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + }, + { + "type": "union", + "name": "AuthMFAEnrollPhoneResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + }, + { + "type": "union", + "name": "AuthMFAEnrollWebauthnResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + ] + } + } + } + } + ] + }, + "@supabase/auth-js.GoTrueMFAApi.getAuthenticatorAssuranceLevel": { + "name": "@supabase/auth-js.GoTrueMFAApi.getAuthenticatorAssuranceLevel", + "params": [ + { + "name": "jwt", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Takes in an optional access token JWT. If no JWT is provided, the JWT from the current session is used." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAGetAuthenticatorAssuranceLevelResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "currentAuthenticationMethods", + "type": { + "type": "union", + "subTypes": [ + { + "type": "array", + "elemType": { + "type": "object", + "name": "AMREntry", + "properties": [ + { + "name": "method", + "type": { + "type": "union", + "name": "AMRMethod", + "subTypes": [ + { + "type": "nameOnly", + "name": "['number']" + }, + null + ] + }, + "comment": { + "shortText": "Authentication method name." + } + }, + { + "name": "timestamp", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the method was successfully used. Represents number of\nseconds since 1st January 1970 (UNIX epoch) in UTC." + } + } + ] + } + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "comment": { + "shortText": "A list of all authentication methods attached to this session. Use\nthe information here to detect the last time a user verified a\nfactor, for example if implementing a step-up scenario.\n\nSupports both RFC-8176 compliant format (string[]) and detailed format (AMREntry[]).\n- String format: ['password', 'otp'] - RFC-8176 compliant\n- Object format: [{ method: 'password', timestamp: 1234567890 }] - includes timestamps" + } + }, + { + "name": "currentLevel", + "type": { + "type": "union", + "subTypes": [ + { + "type": "union", + "name": "AuthenticatorAssuranceLevels", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + }, + { + "type": "literal", + "value": null + } + ] + }, + "comment": { + "shortText": "Current AAL level of the session." + } + }, + { + "name": "nextLevel", + "type": { + "type": "union", + "subTypes": [ + { + "type": "union", + "name": "AuthenticatorAssuranceLevels", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + }, + { + "type": "literal", + "value": null + } + ] + }, + "comment": { + "shortText": "Next possible AAL level for the session. If the next level is higher\nthan the current one, the user should go through MFA." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Returns the Authenticator Assurance Level (AAL) for the active session.\n\n- `aal1` (or `null`) means that the user's identity has been verified only\nwith a conventional login (email+password, OTP, magic link, social login,\netc.).\n- `aal2` means that the user's identity has been verified both with a conventional login and at least one MFA factor.\n\nWhen called without a JWT parameter, this method is fairly quick (microseconds)\nand rarely uses the network. When a JWT is provided (useful in server-side\nenvironments like Edge Functions where no session is stored), this method\nwill make a network request to validate the user and fetch their MFA factors.", + "text": "- Authenticator Assurance Level (AAL) is the measure of the strength of an authentication mechanism.\n- In Supabase, having an AAL of `aal1` refers to having the 1st factor of authentication such as an email and password or OAuth sign-in while `aal2` refers to the 2nd factor of authentication such as a time-based, one-time-password (TOTP) or Phone factor.\n- If the user has a verified factor, the `nextLevel` field will return `aal2`, else, it will return `aal1`.\n- An optional `jwt` parameter can be passed to check the AAL level of a specific JWT instead of the current session.", + "examples": [ + { + "id": "get-the-aal-details-of-a-session", + "name": "Get the AAL details of a session", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.getAuthenticatorAssuranceLevel()\nconst { currentLevel, nextLevel, currentAuthenticationMethods } = data\n```", + "response": "```json\n{\n data: {\n currentLevel: 'aal1',\n nextLevel: 'aal2',\n currentAuthenticationMethods: [\n {\n method: 'password',\n timestamp: 1700000000\n }\n ]\n }\n error: null\n}\n```" + }, + { + "id": "get-the-aal-details-for-a-specific-jwt", + "name": "Get the AAL details for a specific JWT", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.getAuthenticatorAssuranceLevel(jwt)\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueMFAApi.listFactors": { + "name": "@supabase/auth-js.GoTrueMFAApi.listFactors", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAListFactorsResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Returns the list of MFA factors enabled for this user." + } + }, + "@supabase/auth-js.GoTrueMFAApi.unenroll": { + "name": "@supabase/auth-js.GoTrueMFAApi.unenroll", + "params": [ + { + "name": "params", + "type": { + "name": "MFAUnenrollParams", + "type": "object", + "properties": [ + { + "name": "factorId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "ID of the factor being unenrolled." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAUnenrollResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "ID of the factor that was successfully unenrolled." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Unenroll removes a MFA factor.\nA user has to have an `aal2` authenticator level in order to unenroll a `verified` factor.", + "examples": [ + { + "id": "unenroll-a-factor", + "name": "Unenroll a factor", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.unenroll({\n factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',\n})\n```", + "response": "```json\n{\n data: {\n id: ''\n },\n error: null\n}\n```" + } + ] + } + }, + "@supabase/auth-js.GoTrueMFAApi.verify": { + "name": "@supabase/auth-js.GoTrueMFAApi.verify", + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAVerifyTOTPParams" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "AuthMFAVerifyResponseData", + "type": "object", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "New access token (JWT) after successful verification." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "Number of seconds in which the access token will expire." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "Refresh token you can use to obtain new access tokens when expired." + } + }, + { + "name": "token_type", + "type": "[Circular]", + "comment": { + "shortText": "Type of token, always `bearer`." + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "Updated user profile." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Verifies a code against a challenge. The verification code is\nprovided by the user by entering a code seen in their authenticator app.", + "text": "- To verify a challenge, please [create a challenge](/docs/reference/javascript/auth-mfa-challenge) first.", + "examples": [ + { + "id": "verify-a-challenge-for-a-factor", + "name": "Verify a challenge for a factor", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.verify({\n factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',\n challengeId: '4034ae6f-a8ce-4fb5-8ee5-69a5863a7c15',\n code: '123456'\n})\n```", + "response": "```json\n{\n data: {\n access_token: '',\n token_type: 'Bearer',\n expires_in: 3600,\n refresh_token: '',\n user: {\n id: '11111111-1111-1111-1111-111111111111',\n aud: 'authenticated',\n role: 'authenticated',\n email: 'example@email.com',\n email_confirmed_at: '2024-01-01T00:00:00Z',\n phone: '',\n confirmation_sent_at: '2024-01-01T00:00:00Z',\n confirmed_at: '2024-01-01T00:00:00Z',\n last_sign_in_at: '2024-01-01T00:00:00Z',\n app_metadata: {\n provider: 'email',\n providers: [\n \"email\",\n ]\n },\n user_metadata: {},\n identities: [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": true,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"email@example.com\"\n },\n ],\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n is_anonymous: false,\n factors: [\n \"id\": '',\n \"friendly_name\": 'Important Auth App',\n \"factor_type\": 'totp',\n \"status\": 'verified',\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\"\n ]\n }\n }\n error: null\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAVerifyPhoneParams" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "AuthMFAVerifyResponseData", + "type": "object", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "New access token (JWT) after successful verification." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "Number of seconds in which the access token will expire." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "Refresh token you can use to obtain new access tokens when expired." + } + }, + { + "name": "token_type", + "type": "[Circular]", + "comment": { + "shortText": "Type of token, always `bearer`." + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "Updated user profile." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + } + }, + { + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAVerifyWebauthnParams" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "AuthMFAVerifyResponseData", + "type": "object", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "New access token (JWT) after successful verification." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "Number of seconds in which the access token will expire." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "Refresh token you can use to obtain new access tokens when expired." + } + }, + { + "name": "token_type", + "type": "[Circular]", + "comment": { + "shortText": "Type of token, always `bearer`." + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "Updated user profile." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + } + }, + { + "params": [ + { + "name": "params", + "type": { + "type": "union", + "name": "MFAVerifyParams", + "subTypes": [ + { + "type": "nameOnly", + "name": "MFAVerifyTOTPParams" + }, + { + "type": "nameOnly", + "name": "MFAVerifyPhoneParams" + }, + { + "type": "nameOnly", + "name": "MFAVerifyWebauthnParams" + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "AuthMFAVerifyResponseData", + "type": "object", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "New access token (JWT) after successful verification." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "Number of seconds in which the access token will expire." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "Refresh token you can use to obtain new access tokens when expired." + } + }, + { + "name": "token_type", + "type": "[Circular]", + "comment": { + "shortText": "Type of token, always `bearer`." + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "User", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "Updated user profile." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + } + } + ] + }, + "@supabase/auth-js.isAuthApiError": { + "name": "@supabase/auth-js.isAuthApiError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + }, + "@supabase/auth-js.isAuthError": { + "name": "@supabase/auth-js.isAuthError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + }, + "@supabase/auth-js.isAuthImplicitGrantRedirectError": { + "name": "@supabase/auth-js.isAuthImplicitGrantRedirectError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ] + }, + "@supabase/auth-js.isAuthPKCECodeVerifierMissingError": { + "name": "@supabase/auth-js.isAuthPKCECodeVerifierMissingError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + }, + "@supabase/auth-js.isAuthRefreshDiscardedError": { + "name": "@supabase/auth-js.isAuthRefreshDiscardedError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + }, + "@supabase/auth-js.isAuthRetryableFetchError": { + "name": "@supabase/auth-js.isAuthRetryableFetchError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + }, + "@supabase/auth-js.isAuthSessionMissingError": { + "name": "@supabase/auth-js.isAuthSessionMissingError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ] + }, + "@supabase/auth-js.isAuthWeakPasswordError": { + "name": "@supabase/auth-js.isAuthWeakPasswordError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + }, + "@supabase/auth-js.navigatorLock": { + "name": "@supabase/auth-js.navigatorLock", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Name of the lock to be acquired." + } + }, + { + "name": "acquireTimeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "If negative, no timeout. If 0 an error is thrown if\n the lock can't be acquired without waiting. If positive, the lock acquire\n will time out after so many milliseconds. An error is\n a timeout if it has `isAcquireTimeout` set to true." + } + }, + { + "name": "fn", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "R" + } + } + } + }, + "comment": { + "shortText": "The operation to run once the lock is acquired." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "R" + } + } + }, + "comment": { + "shortText": "Implements a global exclusive lock using the Navigator LockManager API. It\nis available on all browsers released after 2022-03-15 with Safari being the\nlast one to release support. If the API is not available, this function will\nthrow. Make sure you check availablility before configuring GoTrueClient.\n\nYou can turn on debugging by setting the `supabase.gotrue-js.locks.debug`\nlocal storage item to `true`.\n\nInternals:\n\nSince the LockManager API does not preserve stack traces for the async\nfunction passed in the `request` method, a trick is used where acquiring the\nlock releases a previously started promise to run the operation in the `fn`\nfunction. The lock waits for that promise to finish (with or without error),\nwhile the function will finally wait for the result anyway." + } + }, + "@supabase/auth-js.processLock": { + "name": "@supabase/auth-js.processLock", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Name of the lock to be acquired." + } + }, + { + "name": "acquireTimeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "If negative, no timeout. If 0 an error is thrown if\n the lock can't be acquired without waiting. If positive, the lock acquire\n will time out after so many milliseconds. An error is\n a timeout if it has `isAcquireTimeout` set to true." + } + }, + { + "name": "fn", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "R" + } + } + } + }, + "comment": { + "shortText": "The operation to run once the lock is acquired." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "R" + } + } + }, + "comment": { + "shortText": "Implements a global exclusive lock that works only in the current process.\nUseful for environments like React Native or other non-browser\nsingle-process (i.e. no concept of \"tabs\") environments.\n\nUse #navigatorLock in browser environments.", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\nawait processLock('migrate', 5000, async () => {\n await runMigration()\n})\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestBuilder.constructor": { + "name": "@supabase/postgrest-js.PostgrestBuilder.constructor", + "params": [ + { + "name": "builder", + "type": { + "type": "object", + "properties": [ + { + "name": "body", + "type": { + "type": "intrinsic", + "name": "unknown" + }, + "isOptional": true + }, + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "URL" + }, + { + "type": "nameOnly", + "name": "RequestInfo" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true + }, + { + "name": "headers", + "type": { + "type": "nameOnly", + "name": "HeadersInit" + } + }, + { + "name": "isMaybeSingle", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "method", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "GET" + }, + { + "type": "literal", + "value": "HEAD" + }, + { + "type": "literal", + "value": "POST" + }, + { + "type": "literal", + "value": "PATCH" + }, + { + "type": "literal", + "value": "DELETE" + } + ] + } + }, + { + "name": "retry", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "schema", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "shouldStripNulls", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "shouldThrowOnError", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "isOptional": true + }, + { + "name": "url", + "type": { + "type": "nameOnly", + "name": "URL" + } + }, + { + "name": "urlLengthLimit", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Creates a builder configured for a specific PostgREST request.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst { data, error } = await supabase.from('users').select('*')\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport { PostgrestQueryBuilder } from '@supabase/postgrest-js'\n\nconst builder = new PostgrestQueryBuilder(\n new URL('https://xyzcompany.supabase.co/rest/v1/users'),\n { headers: new Headers({ apikey: 'your-publishable-key' }) }\n)\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestBuilder.overrideTypes": { + "name": "@supabase/postgrest-js.PostgrestBuilder.overrideTypes", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Override the type of the returned `data` field in the response.", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```typescript\n// Merge with existing types (default behavior)\nconst query = supabase\n .from('users')\n .select()\n .overrideTypes<{ custom_field: string }>()\n\n// Replace existing types completely\nconst replaceQuery = supabase\n .from('users')\n .select()\n .overrideTypes<{ id: number; name: string }, { merge: false }>()\n```" + }, + { + "id": "complete-override-type-of-successful-response", + "name": "Complete Override type of successful response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .overrideTypes, { merge: false }>()\n```", + "response": "```ts\nlet x: typeof data // MyType[]\n```" + }, + { + "id": "complete-override-type-of-object-response", + "name": "Complete Override type of object response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .maybeSingle()\n .overrideTypes()\n```", + "response": "```ts\nlet x: typeof data // MyType | null\n```" + }, + { + "id": "partial-override-type-of-successful-response", + "name": "Partial Override type of successful response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .overrideTypes>()\n```", + "response": "```ts\nlet x: typeof data // Array\n```" + }, + { + "id": "partial-override-type-of-object-response", + "name": "Partial Override type of object response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .maybeSingle()\n .overrideTypes<{ status: \"A\" | \"B\" }>()\n```", + "response": "```ts\nlet x: typeof data // CountryRowProperties & { status: \"A\" | \"B\" } | null\n```" + }, + { + "id": "merge-vs-replace-existing-types", + "name": "Merge vs replace existing types", + "code": "```typescript\n// Merge with existing types (default behavior)\nconst query = supabase\n .from('users')\n .select()\n .overrideTypes<{ custom_field: string }>()\n\n// Replace existing types completely\nconst replaceQuery = supabase\n .from('users')\n .select()\n .overrideTypes<{ id: number; name: string }, { merge: false }>()\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestBuilder.retry": { + "name": "@supabase/postgrest-js.PostgrestBuilder.retry", + "params": [ + { + "name": "enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "comment": { + "shortText": "Whether to enable retries for this request" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\n// Disable retries for a specific query\nconst { data, error } = await supabase\n .from('users')\n .select()\n .retry(false)\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestBuilder.returns": { + "name": "@supabase/postgrest-js.PostgrestBuilder.returns", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Override the type of the returned `data`." + } + }, + "@supabase/postgrest-js.PostgrestBuilder.setHeader": { + "name": "@supabase/postgrest-js.PostgrestBuilder.setHeader", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set an HTTP header for the request." + } + }, + "@supabase/postgrest-js.PostgrestBuilder.stripNulls": { + "name": "@supabase/postgrest-js.PostgrestBuilder.stripNulls", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Strip null values from the response data. Properties with `null` values\nwill be omitted from the returned JSON objects.\n\nRequires PostgREST 11.2.0+.\n\nhttps://docs.postgrest.org/en/stable/references/api/resource_representation.html#stripped-nulls", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .stripNulls()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text, bio text);\n\ninsert into\n characters (id, name, bio)\nvalues\n (1, 'Luke', null),\n (2, 'Leia', 'Princess of Alderaan');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Luke\"\n },\n {\n \"id\": 2,\n \"name\": \"Leia\",\n \"bio\": \"Princess of Alderaan\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestBuilder.then": { + "name": "@supabase/postgrest-js.PostgrestBuilder.then", + "params": [ + { + "name": "onfulfilled", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "value" + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult1" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is resolved." + } + }, + { + "name": "onrejected", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "reason", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult2" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is rejected." + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PromiseLike" + } + }, + "comment": { + "shortText": "Attaches callbacks for the resolution and/or rejection of the Promise." + } + }, + "@supabase/postgrest-js.PostgrestBuilder.throwOnError": { + "name": "@supabase/postgrest-js.PostgrestBuilder.throwOnError", + "params": [], + "comment": { + "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.\n\nhttps://github.com/supabase/supabase-js/issues/92" + } + }, + "@supabase/postgrest-js.PostgrestClient.constructor": { + "name": "@supabase/postgrest-js.PostgrestClient.constructor", + "params": [ + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "URL of the PostgREST endpoint" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "URL" + }, + { + "type": "nameOnly", + "name": "RequestInfo" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true, + "comment": { + "shortText": "Custom fetch" + } + }, + { + "name": "headers", + "type": { + "type": "nameOnly", + "name": "HeadersInit" + }, + "isOptional": true, + "comment": { + "shortText": "Custom headers" + } + }, + { + "name": "retry", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Enable or disable automatic retries for transient errors.\n When enabled, idempotent requests (GET, HEAD, OPTIONS) that fail with network\n errors or HTTP 503/520 responses will be automatically retried up to 3 times\n with exponential backoff (1s, 2s, 4s). Defaults to `true`." + } + }, + { + "name": "schema", + "type": { + "type": "nameOnly", + "name": "@supabase/postgrest-js.default.SchemaName" + }, + "isOptional": true, + "comment": { + "shortText": "Postgres schema to switch to" + } + }, + { + "name": "timeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "Optional timeout in milliseconds for all requests. When set, requests will automatically abort after this duration to prevent indefinite hangs." + } + }, + { + "name": "urlLengthLimit", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "Maximum URL length in characters before warnings/errors are triggered. Defaults to 8000." + } + } + ] + }, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestClient" + } + }, + "comment": { + "shortText": "Creates a PostgREST client.", + "text": "- A `timeout` option (in milliseconds) can be set to automatically abort requests that take too long.\n- A `urlLengthLimit` option (default: 8000) can be set to control when URL length warnings are included in error messages for aborted requests.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst { data, error } = await supabase.from('profiles').select('*')\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport { PostgrestClient } from '@supabase/postgrest-js'\n\nconst postgrest = new PostgrestClient('https://xyzcompany.supabase.co/rest/v1', {\n headers: { apikey: 'your-publishable-key' },\n schema: 'public',\n timeout: 30000, // 30 second timeout\n})\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestClient.from": { + "name": "@supabase/postgrest-js.PostgrestClient.from", + "params": [ + { + "name": "relation", + "type": { + "type": "nameOnly", + "name": "TableName" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestQueryBuilder" + } + }, + "comment": { + "shortText": "Perform a query on a table or a view." + }, + "altSignatures": [ + { + "params": [ + { + "name": "relation", + "type": { + "type": "nameOnly", + "name": "ViewName" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestQueryBuilder" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestClient.rpc": { + "name": "@supabase/postgrest-js.PostgrestClient.rpc", + "params": [ + { + "name": "fn", + "type": { + "type": "nameOnly", + "name": "FnName" + }, + "comment": { + "shortText": "The function name to call" + } + }, + { + "name": "args", + "type": { + "type": "nameOnly", + "name": "Args" + }, + "comment": { + "shortText": "The arguments to pass to the function call" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "count", + "type": { + "type": "union", + "subTypes": [ + null, + { + "type": "literal", + "value": "exact" + }, + { + "type": "literal", + "value": "planned" + }, + { + "type": "literal", + "value": "estimated" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Count algorithm to use to count rows returned by the\nfunction. Only applicable for [set-returning\nfunctions](https://www.postgresql.org/docs/current/functions-srf.html).\n\n`\"exact\"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the\nhood.\n\n`\"planned\"`: Approximated but fast count algorithm. Uses the Postgres\nstatistics under the hood.\n\n`\"estimated\"`: Uses exact count for low numbers and planned count for high\nnumbers." + } + }, + { + "name": "get", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "When set to `true`, the function will be called with\nread-only access mode." + } + }, + { + "name": "head", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "When set to `true`, `data` will not be returned.\nUseful if you only need the count." + } + } + ] + }, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Perform a function call.", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\n// For cross-schema functions where type inference fails, use overrideTypes:\nconst { data } = await supabase\n .schema('schema_b')\n .rpc('function_a', {})\n .overrideTypes<{ id: string; user_id: string }[]>()\n```" + }, + { + "id": "call-a-postgres-function-without-arguments", + "name": "Call a Postgres function without arguments", + "code": "```ts\nconst { data, error } = await supabase.rpc('hello_world')\n```", + "data": { + "sql": "```sql\ncreate function hello_world() returns text as $$\n select 'Hello world';\n$$ language sql;\n```" + }, + "response": "```json\n{\n \"data\": \"Hello world\",\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "call-a-postgres-function-with-arguments", + "name": "Call a Postgres function with arguments", + "code": "```ts\nconst { data, error } = await supabase.rpc('echo', { say: '👋' })\n```", + "data": { + "sql": "```sql\ncreate function echo(say text) returns text as $$\n select say;\n$$ language sql;\n```" + }, + "response": "```json\n {\n \"data\": \"👋\",\n \"status\": 200,\n \"statusText\": \"OK\"\n }\n\n```" + }, + { + "id": "bulk-processing", + "name": "Bulk processing", + "code": "```ts\nconst { data, error } = await supabase.rpc('add_one_each', { arr: [1, 2, 3] })\n```", + "description": "You can process large payloads by passing in an array as an argument.", + "data": { + "sql": "```sql\ncreate function add_one_each(arr int[]) returns int[] as $$\n select array_agg(n + 1) from unnest(arr) as n;\n$$ language sql;\n```" + }, + "response": "```json\n{\n \"data\": [\n 2,\n 3,\n 4\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "call-a-postgres-function-with-filters", + "name": "Call a Postgres function with filters", + "code": "```ts\nconst { data, error } = await supabase\n .rpc('list_stored_countries')\n .eq('id', 1)\n .single()\n```", + "description": "Postgres functions that return tables can also be combined with [Filters](/docs/reference/javascript/using-filters) and [Modifiers](/docs/reference/javascript/using-modifiers).", + "data": { + "sql": "```sql\ncreate table\n countries (id int8 primary key, name text);\n\ninsert into\n countries (id, name)\nvalues\n (1, 'Rohan'),\n (2, 'The Shire');\n\ncreate function list_stored_countries() returns setof countries as $$\n select * from countries;\n$$ language sql;\n```" + }, + "response": "```json\n{\n \"data\": {\n \"id\": 1,\n \"name\": \"Rohan\"\n },\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "call-a-read-only-postgres-function", + "name": "Call a read-only Postgres function", + "code": "```ts\nconst { data, error } = await supabase.rpc('hello_world', undefined, { get: true })\n```", + "data": { + "sql": "```sql\ncreate function hello_world() returns text as $$\n select 'Hello world';\n$$ language sql;\n```" + }, + "response": "```json\n{\n \"data\": \"Hello world\",\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestClient.schema": { + "name": "@supabase/postgrest-js.PostgrestClient.schema", + "params": [ + { + "name": "schema", + "type": { + "type": "nameOnly", + "name": "DynamicSchema" + }, + "comment": { + "shortText": "The schema to query" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestClient" + } + }, + "comment": { + "shortText": "Select a schema to query or perform an function (rpc) call.\n\nThe schema needs to be on the list of exposed schemas inside Supabase." + } + }, + "@supabase/postgrest-js.PostgrestError.constructor": { + "name": "@supabase/postgrest-js.PostgrestError.constructor", + "params": [ + { + "name": "context", + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "details", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "hint", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestError" + } + }, + "comment": { + "shortText": "", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\nimport PostgrestError from '@supabase/postgrest-js'\n\nthrow new PostgrestError({\n message: 'Row level security prevented the request',\n details: 'RLS denied the insert',\n hint: 'Check your policies',\n code: 'PGRST301',\n})\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestError.toJSON": { + "name": "@supabase/postgrest-js.PostgrestError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "details", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "hint", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.constructor": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.constructor", + "params": [ + { + "name": "builder", + "type": { + "type": "object", + "properties": [ + { + "name": "body", + "type": { + "type": "intrinsic", + "name": "unknown" + }, + "isOptional": true + }, + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "URL" + }, + { + "type": "nameOnly", + "name": "RequestInfo" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true + }, + { + "name": "headers", + "type": { + "type": "nameOnly", + "name": "HeadersInit" + } + }, + { + "name": "isMaybeSingle", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "method", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "GET" + }, + { + "type": "literal", + "value": "HEAD" + }, + { + "type": "literal", + "value": "POST" + }, + { + "type": "literal", + "value": "PATCH" + }, + { + "type": "literal", + "value": "DELETE" + } + ] + } + }, + { + "name": "retry", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "schema", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "shouldStripNulls", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "shouldThrowOnError", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "isOptional": true + }, + { + "name": "url", + "type": { + "type": "nameOnly", + "name": "URL" + } + }, + { + "name": "urlLengthLimit", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Creates a builder configured for a specific PostgREST request.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst { data, error } = await supabase.from('users').select('*')\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport { PostgrestQueryBuilder } from '@supabase/postgrest-js'\n\nconst builder = new PostgrestQueryBuilder(\n new URL('https://xyzcompany.supabase.co/rest/v1/users'),\n { headers: new Headers({ apikey: 'your-publishable-key' }) }\n)\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.abortSignal": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.abortSignal", + "params": [ + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "comment": { + "shortText": "The AbortSignal to use for the fetch request" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set the AbortSignal for the fetch request.", + "text": "You can use this to set a timeout for the request.", + "examples": [ + { + "id": "aborting-requests-in-flight", + "name": "Aborting requests in-flight", + "code": "```ts\nconst ac = new AbortController()\n\nconst { data, error } = await supabase\n .from('very_big_table')\n .select()\n .abortSignal(ac.signal)\n\n// Abort the request after 100 ms\nsetTimeout(() => ac.abort(), 100)\n```", + "description": "You can use an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) to abort requests.\nNote that `status` and `statusText` don't mean anything for aborted requests as the request wasn't fulfilled.", + "response": "```json\n {\n \"error\": {\n \"message\": \"AbortError: The user aborted a request.\",\n \"details\": \"\",\n \"hint\": \"The request was aborted locally via the provided AbortSignal.\",\n \"code\": \"\"\n },\n \"status\": 0,\n \"statusText\": \"\"\n }\n\n```" + }, + { + "id": "set-a-timeout", + "name": "Set a timeout", + "code": "```ts\nconst { data, error } = await supabase\n .from('very_big_table')\n .select()\n .abortSignal(AbortSignal.timeout(1000 /* ms */))\n```", + "response": "```json\n {\n \"error\": {\n \"message\": \"FetchError: The user aborted a request.\",\n \"details\": \"\",\n \"hint\": \"\",\n \"code\": \"\"\n },\n \"status\": 400,\n \"statusText\": \"Bad Request\"\n }\n\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.containedBy": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.containedBy", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "value", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "unknown" + } + }, + { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Only relevant for jsonb, array, and range columns. Match only rows where\nevery element appearing in `column` is contained by `value`.", + "examples": [ + { + "id": "on-array-columns", + "name": "On array columns", + "code": "```ts\nconst { data, error } = await supabase\n .from('classes')\n .select('name')\n .containedBy('days', ['monday', 'tuesday', 'wednesday', 'friday'])\n```", + "data": { + "sql": "```sql\ncreate table\n classes (\n id int8 primary key,\n name text,\n days text[]\n );\n\ninsert into\n classes (id, name, days)\nvalues\n (1, 'Chemistry', array['monday', 'friday']),\n (2, 'History', array['monday', 'wednesday', 'thursday']);\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Chemistry\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "on-range-columns", + "name": "On range columns", + "code": "```ts\nconst { data, error } = await supabase\n .from('reservations')\n .select()\n .containedBy('during', '[2000-01-01 00:00, 2000-01-01 23:59)')\n```", + "description": "Postgres supports a number of [range\ntypes](https://www.postgresql.org/docs/current/rangetypes.html). You\ncan filter on range columns using the string representation of range\nvalues.", + "data": { + "sql": "```sql\ncreate table\n reservations (\n id int8 primary key,\n room_name text,\n during tsrange\n );\n\ninsert into\n reservations (id, room_name, during)\nvalues\n (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),\n (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"room_name\": \"Emerald\",\n \"during\": \"[\\\"2000-01-01 13:00:00\\\",\\\"2000-01-01 15:00:00\\\")\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "on-jsonb-columns", + "name": "On `jsonb` columns", + "code": "```ts\nconst { data, error } = await supabase\n .from('users')\n .select('name')\n .containedBy('address', {})\n```", + "data": { + "sql": "```sql\ncreate table\n users (\n id int8 primary key,\n name text,\n address jsonb\n );\n\ninsert into\n users (id, name, address)\nvalues\n (1, 'Michael', '{ \"postcode\": 90210, \"street\": \"Melrose Place\" }'),\n (2, 'Jane', '{}');\n```" + }, + "response": "```json\n {\n \"data\": [\n {\n \"name\": \"Jane\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n }\n\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "unknown" + } + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.contains": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.contains", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "value", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "unknown" + } + }, + { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Only relevant for jsonb, array, and range columns. Match only rows where\n`column` contains every element appearing in `value`.", + "examples": [ + { + "id": "on-array-columns", + "name": "On array columns", + "code": "```ts\nconst { data, error } = await supabase\n .from('issues')\n .select()\n .contains('tags', ['is:open', 'priority:low'])\n```", + "data": { + "sql": "```sql\ncreate table\n issues (\n id int8 primary key,\n title text,\n tags text[]\n );\n\ninsert into\n issues (id, title, tags)\nvalues\n (1, 'Cache invalidation is not working', array['is:open', 'severity:high', 'priority:low']),\n (2, 'Use better names', array['is:open', 'severity:low', 'priority:medium']);\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"title\": \"Cache invalidation is not working\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "on-range-columns", + "name": "On range columns", + "code": "```ts\nconst { data, error } = await supabase\n .from('reservations')\n .select()\n .contains('during', '[2000-01-01 13:00, 2000-01-01 13:30)')\n```", + "description": "Postgres supports a number of [range\ntypes](https://www.postgresql.org/docs/current/rangetypes.html). You\ncan filter on range columns using the string representation of range\nvalues.", + "data": { + "sql": "```sql\ncreate table\n reservations (\n id int8 primary key,\n room_name text,\n during tsrange\n );\n\ninsert into\n reservations (id, room_name, during)\nvalues\n (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),\n (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"room_name\": \"Emerald\",\n \"during\": \"[\\\"2000-01-01 13:00:00\\\",\\\"2000-01-01 15:00:00\\\")\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "on-jsonb-columns", + "name": "On `jsonb` columns", + "code": "```ts\nconst { data, error } = await supabase\n .from('users')\n .select('name')\n .contains('address', { postcode: 90210 })\n```", + "data": { + "sql": "```sql\ncreate table\n users (\n id int8 primary key,\n name text,\n address jsonb\n );\n\ninsert into\n users (id, name, address)\nvalues\n (1, 'Michael', '{ \"postcode\": 90210, \"street\": \"Melrose Place\" }'),\n (2, 'Jane', '{}');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Michael\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "unknown" + } + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.csv": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.csv", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Return `data` as a string in CSV format.", + "examples": [ + { + "id": "return-data-as-csv", + "name": "Return data as CSV", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .csv()\n```", + "description": "By default, the data is returned in JSON format, but can also be returned as Comma Separated Values.", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": \"id,name\\n1,Luke\\n2,Leia\\n3,Han\",\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.eq": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.eq", + "params": [ + { + "name": "column", + "comment": { + "shortText": "The column to filter on" + } + }, + { + "name": "value", + "comment": { + "shortText": "The value to filter with" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` is equal to `value`.\n\nTo check if the value of `column` is NULL, you should use `.is()` instead.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .eq('name', 'Leia')\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 2,\n \"name\": \"Leia\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.explain": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.explain", + "params": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "analyze", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, the query will be executed and the\nactual run time will be returned" + } + }, + { + "name": "buffers", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, include information on buffer usage" + } + }, + { + "name": "format", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "text" + }, + { + "type": "literal", + "value": "json" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The format of the output, can be `\"text\"` (default)\nor `\"json\"`" + } + }, + { + "name": "settings", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, include information on configuration\nparameters that affect query planning" + } + }, + { + "name": "verbose", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, the query identifier will be returned\nand `data` will include the output columns of the query" + } + }, + { + "name": "wal", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, include information on WAL record generation" + } + } + ] + }, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "PostgrestBuilder" + }, + { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + ] + } + }, + "comment": { + "shortText": "Return `data` as the EXPLAIN plan for the query.\n\nYou need to enable the\n[db_plan_enabled](https://supabase.com/docs/guides/database/debugging-performance#enabling-explain)\nsetting before using this method.", + "examples": [ + { + "id": "get-the-execution-plan", + "name": "Get the execution plan", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .explain()\n```", + "description": "By default, the data is returned in TEXT format, but can also be returned as JSON by using the `format` parameter.", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```js\nAggregate (cost=33.34..33.36 rows=1 width=112)\n -> Limit (cost=0.00..18.33 rows=1000 width=40)\n -> Seq Scan on characters (cost=0.00..22.00 rows=1200 width=40)\n```" + }, + { + "id": "get-the-execution-plan-with-analyze-and-verbose", + "name": "Get the execution plan with analyze and verbose", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .explain({analyze:true,verbose:true})\n```", + "description": "By default, the data is returned in TEXT format, but can also be returned as JSON by using the `format` parameter.", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```js\nAggregate (cost=33.34..33.36 rows=1 width=112) (actual time=0.041..0.041 rows=1 loops=1)\n Output: NULL::bigint, count(ROW(characters.id, characters.name)), COALESCE(json_agg(ROW(characters.id, characters.name)), '[]'::json), NULLIF(current_setting('response.headers'::text, true), ''::text), NULLIF(current_setting('response.status'::text, true), ''::text)\n -> Limit (cost=0.00..18.33 rows=1000 width=40) (actual time=0.005..0.006 rows=3 loops=1)\n Output: characters.id, characters.name\n -> Seq Scan on public.characters (cost=0.00..22.00 rows=1200 width=40) (actual time=0.004..0.005 rows=3 loops=1)\n Output: characters.id, characters.name\nQuery Identifier: -4730654291623321173\nPlanning Time: 0.407 ms\nExecution Time: 0.119 ms\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.filter": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.filter", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "operator", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "FilterOperator" + }, + { + "type": "literal", + "value": "not.match" + }, + { + "type": "literal", + "value": "not.is" + }, + { + "type": "literal", + "value": "not.eq" + }, + { + "type": "literal", + "value": "not.neq" + }, + { + "type": "literal", + "value": "not.gt" + }, + { + "type": "literal", + "value": "not.gte" + }, + { + "type": "literal", + "value": "not.lt" + }, + { + "type": "literal", + "value": "not.lte" + }, + { + "type": "literal", + "value": "not.like" + }, + { + "type": "literal", + "value": "not.ilike" + }, + { + "type": "literal", + "value": "not.isdistinct" + }, + { + "type": "literal", + "value": "not.in" + }, + { + "type": "literal", + "value": "not.cs" + }, + { + "type": "literal", + "value": "not.cd" + }, + { + "type": "literal", + "value": "not.sl" + }, + { + "type": "literal", + "value": "not.sr" + }, + { + "type": "literal", + "value": "not.nxl" + }, + { + "type": "literal", + "value": "not.nxr" + }, + { + "type": "literal", + "value": "not.adj" + }, + { + "type": "literal", + "value": "not.ov" + }, + { + "type": "literal", + "value": "not.fts" + }, + { + "type": "literal", + "value": "not.plfts" + }, + { + "type": "literal", + "value": "not.phfts" + }, + { + "type": "literal", + "value": "not.wfts" + }, + { + "type": "literal", + "value": "not.imatch" + } + ] + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows which satisfy the filter. This is an escape hatch - you\nshould use the specific filter methods wherever possible.\n\nUnlike most filters, `opearator` and `value` are used as-is and need to\nfollow [PostgREST\nsyntax](https://postgrest.org/en/stable/api.html#operators). You also need\nto make sure they are properly sanitized.", + "text": "filter() expects you to use the raw PostgREST syntax for the filter values.\n\n```ts\n.filter('id', 'in', '(5,6,7)') // Use `()` for `in` filter\n.filter('arraycol', 'cs', '{\"a\",\"b\"}') // Use `cs` for `contains()`, `{}` for array values\n```", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .filter('name', 'in', '(\"Han\",\"Yoda\")')\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 3,\n \"name\": \"Han\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "on-a-referenced-table", + "name": "On a referenced table", + "code": "```ts\nconst { data, error } = await supabase\n .from('orchestral_sections')\n .select(`\n name,\n instruments!inner (\n name\n )\n `)\n .filter('instruments.name', 'eq', 'flute')\n```", + "data": { + "sql": "```sql\ncreate table\n orchestral_sections (id int8 primary key, name text);\ncreate table\n instruments (\n id int8 primary key,\n section_id int8 not null references orchestral_sections,\n name text\n );\n\ninsert into\n orchestral_sections (id, name)\nvalues\n (1, 'strings'),\n (2, 'woodwinds');\ninsert into\n instruments (id, section_id, name)\nvalues\n (1, 2, 'flute'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"woodwinds\",\n \"instruments\": [\n {\n \"name\": \"flute\"\n }\n ]\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "operator", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.geojson": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.geojson", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Return `data` as an object in [GeoJSON](https://geojson.org) format." + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.gt": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.gt", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "value", + "type": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` is greater than `value`.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .gt('id', 2)\n```", + "description": "When using [reserved words](https://www.postgresql.org/docs/current/sql-keywords-appendix.html) for column names you need\nto add double quotes e.g. `.gt('\"order\"', 2)`", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 3,\n \"name\": \"Han\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.gte": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.gte", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "value", + "type": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` is greater than or equal to `value`.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .gte('id', 2)\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 2,\n \"name\": \"Leia\"\n },\n {\n \"id\": 3,\n \"name\": \"Han\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.ilike": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.ilike", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "pattern", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` matches `pattern` case-insensitively.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .ilike('name', '%lu%')\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Luke\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "pattern", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.ilikeAllOf": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.ilikeAllOf", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "patterns", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` matches all of `patterns` case-insensitively." + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "patterns", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.ilikeAnyOf": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.ilikeAnyOf", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "patterns", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` matches any of `patterns` case-insensitively." + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "patterns", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.in": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.in", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + }, + "comment": { + "shortText": "The column to filter on" + } + }, + { + "name": "values", + "type": { + "type": "array" + }, + "comment": { + "shortText": "The values array to filter with" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` is included in the `values` array.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .in('name', ['Leia', 'Han'])\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 2,\n \"name\": \"Leia\"\n },\n {\n \"id\": 3,\n \"name\": \"Han\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.is": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.is", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "value" + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` IS `value`.\n\nFor non-boolean columns, this is only relevant for checking if the value of\n`column` is NULL by setting `value` to `null`.\n\nFor boolean columns, you can also set `value` to `true` or `false` and it\nwill behave the same way as `.eq()`.", + "examples": [ + { + "id": "checking-for-nullness-true-or-false", + "name": "Checking for nullness, true or false", + "code": "```ts\nconst { data, error } = await supabase\n .from('countries')\n .select()\n .is('name', null)\n```", + "description": "Using the `eq()` filter doesn't work when filtering for `null`.\n\nInstead, you need to use `is()`.", + "data": { + "sql": "```sql\ncreate table\n countries (id int8 primary key, name text);\n\ninsert into\n countries (id, name)\nvalues\n (1, 'null'),\n (2, null);\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 2,\n \"name\": \"null\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "boolean" + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.isDistinct": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.isDistinct", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + }, + "comment": { + "shortText": "The column to filter on" + } + }, + { + "name": "value", + "comment": { + "shortText": "The value to filter with" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` IS DISTINCT FROM `value`.\n\nUnlike `.neq()`, this treats `NULL` as a comparable value. Two `NULL` values\nare considered equal (not distinct), and comparing `NULL` with any non-NULL\nvalue returns true (distinct)." + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.like": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.like", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "pattern", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` matches `pattern` case-sensitively.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .like('name', '%Lu%')\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Luke\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "pattern", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.likeAllOf": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.likeAllOf", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "patterns", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` matches all of `patterns` case-sensitively." + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "patterns", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.likeAnyOf": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.likeAnyOf", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "patterns", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` matches any of `patterns` case-sensitively." + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "patterns", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.limit": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.limit", + "params": [ + { + "name": "rows", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The maximum number of rows to return" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Deprecated, use `options.referencedTable`\ninstead" + } + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Set this to limit rows of referenced\ntables instead of the parent table" + } + } + ] + }, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Limit the query result by `rows`.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .limit(1)\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Luke\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "on-a-referenced-table", + "name": "On a referenced table", + "code": "```ts\nconst { data, error } = await supabase\n .from('orchestral_sections')\n .select(`\n name,\n instruments (\n name\n )\n `)\n .limit(1, { referencedTable: 'instruments' })\n```", + "data": { + "sql": "```sql\ncreate table\n orchestral_sections (id int8 primary key, name text);\ncreate table\n instruments (\n id int8 primary key,\n section_id int8 not null references orchestral_sections,\n name text\n );\n\ninsert into\n orchestral_sections (id, name)\nvalues\n (1, 'strings');\ninsert into\n instruments (id, section_id, name)\nvalues\n (1, 1, 'harp'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"strings\",\n \"instruments\": [\n {\n \"name\": \"violin\"\n }\n ]\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.lt": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.lt", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "value", + "type": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` is less than `value`.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .lt('id', 2)\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Luke\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.lte": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.lte", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "value", + "type": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` is less than or equal to `value`.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .lte('id', 2)\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Luke\"\n },\n {\n \"id\": 2,\n \"name\": \"Leia\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.match": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.match", + "params": [ + { + "name": "query", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "nameOnly", + "name": "ColumnName" + }, + "valueType": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where each column in `query` keys is equal to its\nassociated value. Shorthand for multiple `.eq()`s.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .match({ id: 2, name: 'Leia' })\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Leia\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "query", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "unknown" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.maxAffected": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.maxAffected", + "params": [ + { + "name": "rows", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The maximum number of rows that can be affected" + } + } + ], + "comment": { + "shortText": "Set the maximum number of rows that can be affected by the query.\nOnly available in PostgREST v13+ and only works with PATCH and DELETE methods." + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.maybeSingle": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.maybeSingle", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Return `data` as a single object instead of an array of objects.\n\nQuery result must be zero or one row (e.g. using `.limit(1)`), otherwise\nthis returns an error.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .eq('name', 'Katniss')\n .maybeSingle()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.neq": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.neq", + "params": [ + { + "name": "column", + "comment": { + "shortText": "The column to filter on" + } + }, + { + "name": "value", + "comment": { + "shortText": "The value to filter with" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` is not equal to `value`.\n\nThis filter does not include rows where `column` is `NULL`. To match null\nvalues, use `.is(column, null)` instead.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .neq('name', 'Leia')\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Luke\"\n },\n {\n \"id\": 3,\n \"name\": \"Han\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.not": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.not", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "operator", + "type": { + "type": "literal", + "value": "is" + } + }, + { + "name": "value", + "type": { + "type": "literal", + "value": null + } + } + ], + "comment": { + "shortText": "Match only rows which doesn't satisfy the filter.\n\nUnlike most filters, `opearator` and `value` are used as-is and need to\nfollow [PostgREST\nsyntax](https://postgrest.org/en/stable/api.html#operators). You also need\nto make sure they are properly sanitized.", + "text": "not() expects you to use the raw PostgREST syntax for the filter values.\n\n```ts\n.not('id', 'in', '(5,6,7)') // Use `()` for `in` filter\n.not('arraycol', 'cs', '{\"a\",\"b\"}') // Use `cs` for `contains()`, `{}` for array values\n```", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('countries')\n .select()\n .not('name', 'is', null)\n```", + "data": { + "sql": "```sql\ncreate table\n countries (id int8 primary key, name text);\n\ninsert into\n countries (id, name)\nvalues\n (1, 'null'),\n (2, null);\n```" + }, + "response": "```json\n {\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"null\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n }\n\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "operator", + "type": { + "type": "nameOnly", + "name": "FilterOperator" + } + }, + { + "name": "value", + "type": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + }, + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "operator", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.notIn": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.notIn", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + }, + "comment": { + "shortText": "The column to filter on" + } + }, + { + "name": "values", + "type": { + "type": "array" + }, + "comment": { + "shortText": "The values array to filter with" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` is NOT included in the `values` array." + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.or": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.or", + "params": [ + { + "name": "filters", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The filters to use, following PostgREST syntax" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Deprecated, use `referencedTable` instead" + } + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Set this to filter on referenced tables\ninstead of the parent table" + } + } + ] + }, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows which satisfy at least one of the filters.\n\nUnlike most filters, `filters` is used as-is and needs to follow [PostgREST\nsyntax](https://postgrest.org/en/stable/api.html#operators). You also need\nto make sure it's properly sanitized.\n\nIt's currently not possible to do an `.or()` filter across multiple tables.", + "text": "or() expects you to use the raw PostgREST syntax for the filter names and values.\n\n```ts\n.or('id.in.(5,6,7), arraycol.cs.{\"a\",\"b\"}') // Use `()` for `in` filter, `{}` for array values and `cs` for `contains()`.\n.or('id.in.(5,6,7), arraycol.cd.{\"a\",\"b\"}') // Use `cd` for `containedBy()`\n```", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .or('id.eq.2,name.eq.Han')\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Leia\"\n },\n {\n \"name\": \"Han\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "use-or-with-and", + "name": "Use `or` with `and`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .or('id.gt.3,and(id.eq.1,name.eq.Luke)')\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Luke\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "use-or-on-referenced-tables", + "name": "Use `or` on referenced tables", + "code": "```ts\nconst { data, error } = await supabase\n .from('orchestral_sections')\n .select(`\n name,\n instruments!inner (\n name\n )\n `)\n .or('section_id.eq.1,name.eq.guzheng', { referencedTable: 'instruments' })\n```", + "data": { + "sql": "```sql\ncreate table\n orchestral_sections (id int8 primary key, name text);\ncreate table\n instruments (\n id int8 primary key,\n section_id int8 not null references orchestral_sections,\n name text\n );\n\ninsert into\n orchestral_sections (id, name)\nvalues\n (1, 'strings'),\n (2, 'woodwinds');\ninsert into\n instruments (id, section_id, name)\nvalues\n (1, 2, 'flute'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"strings\",\n \"instruments\": [\n {\n \"name\": \"violin\"\n }\n ]\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.order": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.order", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "ascending", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "nullsFirst", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "undefined" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Order the query result by `column`.\n\nYou can call this method multiple times to order by multiple columns.\n\nYou can order referenced tables, but it only affects the ordering of the\nparent table if you use `!inner` in the query.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('id, name')\n .order('id', { ascending: false })\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 3,\n \"name\": \"Han\"\n },\n {\n \"id\": 2,\n \"name\": \"Leia\"\n },\n {\n \"id\": 1,\n \"name\": \"Luke\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "on-a-referenced-table", + "name": "On a referenced table", + "code": "```ts\n const { data, error } = await supabase\n .from('orchestral_sections')\n .select(`\n name,\n instruments (\n name\n )\n `)\n .order('name', { referencedTable: 'instruments', ascending: false })\n\n```", + "description": "Ordering with `referencedTable` doesn't affect the ordering of the\nparent table.", + "data": { + "sql": "```sql\ncreate table\n orchestral_sections (id int8 primary key, name text);\ncreate table\n instruments (\n id int8 primary key,\n section_id int8 not null references orchestral_sections,\n name text\n );\n\ninsert into\n orchestral_sections (id, name)\nvalues\n (1, 'strings'),\n (2, 'woodwinds');\ninsert into\n instruments (id, section_id, name)\nvalues\n (1, 1, 'harp'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"strings\",\n \"instruments\": [\n {\n \"name\": \"violin\"\n },\n {\n \"name\": \"harp\"\n }\n ]\n },\n {\n \"name\": \"woodwinds\",\n \"instruments\": []\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "order-parent-table-by-a-referenced-table", + "name": "Order parent table by a referenced table", + "code": "```ts\n const { data, error } = await supabase\n .from('instruments')\n .select(`\n name,\n section:orchestral_sections (\n name\n )\n `)\n .order('section(name)', { ascending: true })\n\n```", + "description": "Ordering with `referenced_table(col)` affects the ordering of the\nparent table.", + "data": { + "sql": "```sql\ncreate table\n orchestral_sections (id int8 primary key, name text);\ncreate table\n instruments (\n id int8 primary key,\n section_id int8 not null references orchestral_sections,\n name text\n );\n\ninsert into\n orchestral_sections (id, name)\nvalues\n (1, 'strings'),\n (2, 'woodwinds');\ninsert into\n instruments (id, section_id, name)\nvalues\n (1, 2, 'flute'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"violin\",\n \"orchestral_sections\": {\"name\": \"strings\"}\n },\n {\n \"name\": \"flute\",\n \"orchestral_sections\": {\"name\": \"woodwinds\"}\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "ascending", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "nullsFirst", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + }, + { + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "ascending", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "undefined" + }, + "isOptional": true + }, + { + "name": "nullsFirst", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + }, + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "ascending", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "nullsFirst", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.overlaps": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.overlaps", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "value", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Only relevant for array and range columns. Match only rows where\n`column` and `value` have an element in common.", + "examples": [ + { + "id": "on-array-columns", + "name": "On array columns", + "code": "```ts\nconst { data, error } = await supabase\n .from('issues')\n .select('title')\n .overlaps('tags', ['is:closed', 'severity:high'])\n```", + "data": { + "sql": "```sql\ncreate table\n issues (\n id int8 primary key,\n title text,\n tags text[]\n );\n\ninsert into\n issues (id, title, tags)\nvalues\n (1, 'Cache invalidation is not working', array['is:open', 'severity:high', 'priority:low']),\n (2, 'Use better names', array['is:open', 'severity:low', 'priority:medium']);\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"title\": \"Cache invalidation is not working\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "on-range-columns", + "name": "On range columns", + "code": "```ts\nconst { data, error } = await supabase\n .from('reservations')\n .select()\n .overlaps('during', '[2000-01-01 12:45, 2000-01-01 13:15)')\n```", + "description": "Postgres supports a number of [range\ntypes](https://www.postgresql.org/docs/current/rangetypes.html). You\ncan filter on range columns using the string representation of range\nvalues.", + "data": { + "sql": "```sql\ncreate table\n reservations (\n id int8 primary key,\n room_name text,\n during tsrange\n );\n\ninsert into\n reservations (id, room_name, during)\nvalues\n (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),\n (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"room_name\": \"Emerald\",\n \"during\": \"[\\\"2000-01-01 13:00:00\\\",\\\"2000-01-01 15:00:00\\\")\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.overrideTypes": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.overrideTypes", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Override the type of the returned `data` field in the response.", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```typescript\n// Merge with existing types (default behavior)\nconst query = supabase\n .from('users')\n .select()\n .overrideTypes<{ custom_field: string }>()\n\n// Replace existing types completely\nconst replaceQuery = supabase\n .from('users')\n .select()\n .overrideTypes<{ id: number; name: string }, { merge: false }>()\n```" + }, + { + "id": "complete-override-type-of-successful-response", + "name": "Complete Override type of successful response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .overrideTypes, { merge: false }>()\n```", + "response": "```ts\nlet x: typeof data // MyType[]\n```" + }, + { + "id": "complete-override-type-of-object-response", + "name": "Complete Override type of object response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .maybeSingle()\n .overrideTypes()\n```", + "response": "```ts\nlet x: typeof data // MyType | null\n```" + }, + { + "id": "partial-override-type-of-successful-response", + "name": "Partial Override type of successful response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .overrideTypes>()\n```", + "response": "```ts\nlet x: typeof data // Array\n```" + }, + { + "id": "partial-override-type-of-object-response", + "name": "Partial Override type of object response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .maybeSingle()\n .overrideTypes<{ status: \"A\" | \"B\" }>()\n```", + "response": "```ts\nlet x: typeof data // CountryRowProperties & { status: \"A\" | \"B\" } | null\n```" + }, + { + "id": "merge-vs-replace-existing-types", + "name": "Merge vs replace existing types", + "code": "```typescript\n// Merge with existing types (default behavior)\nconst query = supabase\n .from('users')\n .select()\n .overrideTypes<{ custom_field: string }>()\n\n// Replace existing types completely\nconst replaceQuery = supabase\n .from('users')\n .select()\n .overrideTypes<{ id: number; name: string }, { merge: false }>()\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.range": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.range", + "params": [ + { + "name": "from", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The starting index from which to limit the result" + } + }, + { + "name": "to", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The last index to which to limit the result" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Deprecated, use `options.referencedTable`\ninstead" + } + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Set this to limit rows of referenced\ntables instead of the parent table" + } + } + ] + }, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Limit the query result by starting at an offset `from` and ending at the offset `to`.\nOnly records within this range are returned.\nThis respects the query order and if there is no order clause the range could behave unexpectedly.\nThe `from` and `to` values are 0-based and inclusive: `range(1, 3)` will include the second, third\nand fourth rows of the query.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .range(0, 1)\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Luke\"\n },\n {\n \"name\": \"Leia\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.rangeAdjacent": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeAdjacent", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Only relevant for range columns. Match only rows where `column` is\nmutually exclusive to `range` and there can be no element between the two\nranges.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('reservations')\n .select()\n .rangeAdjacent('during', '[2000-01-01 12:00, 2000-01-01 13:00)')\n```", + "description": "Postgres supports a number of [range\ntypes](https://www.postgresql.org/docs/current/rangetypes.html). You\ncan filter on range columns using the string representation of range\nvalues.", + "data": { + "sql": "```sql\ncreate table\n reservations (\n id int8 primary key,\n room_name text,\n during tsrange\n );\n\ninsert into\n reservations (id, room_name, during)\nvalues\n (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),\n (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"room_name\": \"Emerald\",\n \"during\": \"[\\\"2000-01-01 13:00:00\\\",\\\"2000-01-01 15:00:00\\\")\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.rangeGt": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeGt", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Only relevant for range columns. Match only rows where every element in\n`column` is greater than any element in `range`.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('reservations')\n .select()\n .rangeGt('during', '[2000-01-02 08:00, 2000-01-02 09:00)')\n```", + "description": "Postgres supports a number of [range\ntypes](https://www.postgresql.org/docs/current/rangetypes.html). You\ncan filter on range columns using the string representation of range\nvalues.", + "data": { + "sql": "```sql\ncreate table\n reservations (\n id int8 primary key,\n room_name text,\n during tsrange\n );\n\ninsert into\n reservations (id, room_name, during)\nvalues\n (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),\n (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');\n```" + }, + "response": "```json\n {\n \"data\": [\n {\n \"id\": 2,\n \"room_name\": \"Topaz\",\n \"during\": \"[\\\"2000-01-02 09:00:00\\\",\\\"2000-01-02 10:00:00\\\")\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n }\n\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.rangeGte": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeGte", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Only relevant for range columns. Match only rows where every element in\n`column` is either contained in `range` or greater than any element in\n`range`.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('reservations')\n .select()\n .rangeGte('during', '[2000-01-02 08:30, 2000-01-02 09:30)')\n```", + "description": "Postgres supports a number of [range\ntypes](https://www.postgresql.org/docs/current/rangetypes.html). You\ncan filter on range columns using the string representation of range\nvalues.", + "data": { + "sql": "```sql\ncreate table\n reservations (\n id int8 primary key,\n room_name text,\n during tsrange\n );\n\ninsert into\n reservations (id, room_name, during)\nvalues\n (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),\n (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');\n```" + }, + "response": "```json\n {\n \"data\": [\n {\n \"id\": 2,\n \"room_name\": \"Topaz\",\n \"during\": \"[\\\"2000-01-02 09:00:00\\\",\\\"2000-01-02 10:00:00\\\")\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n }\n\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.rangeLt": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeLt", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Only relevant for range columns. Match only rows where every element in\n`column` is less than any element in `range`.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('reservations')\n .select()\n .rangeLt('during', '[2000-01-01 15:00, 2000-01-01 16:00)')\n```", + "description": "Postgres supports a number of [range\ntypes](https://www.postgresql.org/docs/current/rangetypes.html). You\ncan filter on range columns using the string representation of range\nvalues.", + "data": { + "sql": "```sql\ncreate table\n reservations (\n id int8 primary key,\n room_name text,\n during tsrange\n );\n\ninsert into\n reservations (id, room_name, during)\nvalues\n (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),\n (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"room_name\": \"Emerald\",\n \"during\": \"[\\\"2000-01-01 13:00:00\\\",\\\"2000-01-01 15:00:00\\\")\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.rangeLte": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeLte", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Only relevant for range columns. Match only rows where every element in\n`column` is either contained in `range` or less than any element in\n`range`.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('reservations')\n .select()\n .rangeLte('during', '[2000-01-01 14:00, 2000-01-01 16:00)')\n```", + "description": "Postgres supports a number of [range\ntypes](https://www.postgresql.org/docs/current/rangetypes.html). You\ncan filter on range columns using the string representation of range\nvalues.", + "data": { + "sql": "```sql\ncreate table\n reservations (\n id int8 primary key,\n room_name text,\n during tsrange\n );\n\ninsert into\n reservations (id, room_name, during)\nvalues\n (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),\n (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');\n```" + }, + "response": "```json\n {\n \"data\": [\n {\n \"id\": 1,\n \"room_name\": \"Emerald\",\n \"during\": \"[\\\"2000-01-01 13:00:00\\\",\\\"2000-01-01 15:00:00\\\")\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n }\n\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.regexIMatch": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.regexIMatch", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "pattern", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` matches the PostgreSQL regex `pattern`\ncase-insensitively (using the `~*` operator)." + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "pattern", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.regexMatch": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.regexMatch", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "pattern", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` matches the PostgreSQL regex `pattern`\ncase-sensitively (using the `~` operator)." + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "pattern", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.retry": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.retry", + "params": [ + { + "name": "enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "comment": { + "shortText": "Whether to enable retries for this request" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\n// Disable retries for a specific query\nconst { data, error } = await supabase\n .from('users')\n .select()\n .retry(false)\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.returns": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.returns", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestTransformBuilder" + } + }, + "comment": { + "shortText": "Override the type of the returned `data`.", + "text": "- Deprecated: use overrideTypes method instead", + "examples": [ + { + "id": "override-type-of-successful-response", + "name": "Override type of successful response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .returns>()\n```", + "response": "```js\nlet x: typeof data // MyType[]\n```" + }, + { + "id": "override-type-of-object-response", + "name": "Override type of object response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .maybeSingle()\n .returns()\n```", + "response": "```js\nlet x: typeof data // MyType | null\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.rollback": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.rollback", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Rollback the query.\n\n`data` will still be returned, but the query is not committed." + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.select": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.select", + "params": [ + { + "name": "columns", + "type": { + "type": "nameOnly", + "name": "Query" + }, + "isOptional": true, + "comment": { + "shortText": "The columns to retrieve, separated by commas" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Perform a SELECT on the query result.\n\nBy default, `.insert()`, `.update()`, `.upsert()`, and `.delete()` do not\nreturn modified rows. By calling this method, modified rows are returned in\n`data`.", + "examples": [ + { + "id": "with-upsert", + "name": "With `upsert()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .upsert({ id: 1, name: 'Han Solo' })\n .select()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Han Solo\"\n }\n ],\n \"status\": 201,\n \"statusText\": \"Created\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.setHeader": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.setHeader", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set an HTTP header for the request." + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.single": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.single", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Return `data` as a single object instead of an array of objects.\n\nQuery result must be one row (e.g. using `.limit(1)`), otherwise this\nreturns an error.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .limit(1)\n .single()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": {\n \"name\": \"Luke\"\n },\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.stripNulls": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.stripNulls", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Strip null values from the response data. Properties with `null` values\nwill be omitted from the returned JSON objects.\n\nRequires PostgREST 11.2.0+.\n\nhttps://docs.postgrest.org/en/stable/references/api/resource_representation.html#stripped-nulls", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .stripNulls()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text, bio text);\n\ninsert into\n characters (id, name, bio)\nvalues\n (1, 'Luke', null),\n (2, 'Leia', 'Princess of Alderaan');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Luke\"\n },\n {\n \"id\": 2,\n \"name\": \"Leia\",\n \"bio\": \"Princess of Alderaan\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.textSearch": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.textSearch", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "query", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "config", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "plain" + }, + { + "type": "literal", + "value": "phrase" + }, + { + "type": "literal", + "value": "websearch" + } + ] + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Only relevant for text and tsvector columns. Match only rows where\n`column` matches the query string in `query`.", + "text": "- For more information, see [Postgres full text search](/docs/guides/database/full-text-search).", + "examples": [ + { + "id": "text-search", + "name": "Text search", + "code": "```ts\nconst result = await supabase\n .from(\"texts\")\n .select(\"content\")\n .textSearch(\"content\", `'eggs' & 'ham'`, {\n config: \"english\",\n });\n```", + "data": { + "sql": "```sql\ncreate table texts (\n id bigint\n primary key\n generated always as identity,\n content text\n);\n\ninsert into texts (content) values\n ('Four score and seven years ago'),\n ('The road goes ever on and on'),\n ('Green eggs and ham')\n;\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"content\": \"Green eggs and ham\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "basic-normalization", + "name": "Basic normalization", + "code": "```ts\nconst { data, error } = await supabase\n .from('quotes')\n .select('catchphrase')\n .textSearch('catchphrase', `'fat' & 'cat'`, {\n type: 'plain',\n config: 'english'\n })\n```", + "description": "Uses PostgreSQL's `plainto_tsquery` function." + }, + { + "id": "full-normalization", + "name": "Full normalization", + "code": "```ts\nconst { data, error } = await supabase\n .from('quotes')\n .select('catchphrase')\n .textSearch('catchphrase', `'fat' & 'cat'`, {\n type: 'phrase',\n config: 'english'\n })\n```", + "description": "Uses PostgreSQL's `phraseto_tsquery` function." + }, + { + "id": "websearch", + "name": "Websearch", + "code": "```ts\nconst { data, error } = await supabase\n .from('quotes')\n .select('catchphrase')\n .textSearch('catchphrase', `'fat or cat'`, {\n type: 'websearch',\n config: 'english'\n })\n```", + "description": "Uses PostgreSQL's `websearch_to_tsquery` function.\nThis function will never raise syntax errors, which makes it possible to use raw user-supplied input for search, and can be used\nwith advanced operators.\n\n- `unquoted text`: text not inside quote marks will be converted to terms separated by & operators, as if processed by plainto_tsquery.\n- `\"quoted text\"`: text inside quote marks will be converted to terms separated by `<->` operators, as if processed by phraseto_tsquery.\n- `OR`: the word “or” will be converted to the | operator.\n- `-`: a dash will be converted to the ! operator." + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "query", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "config", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "plain" + }, + { + "type": "literal", + "value": "phrase" + }, + { + "type": "literal", + "value": "websearch" + } + ] + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.then": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.then", + "params": [ + { + "name": "onfulfilled", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "value", + "type": { + "type": "union", + "name": "PostgrestSingleResponse", + "subTypes": [ + { + "type": "object", + "name": "PostgrestResponseSuccess", + "properties": [ + { + "name": "count", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + }, + { + "name": "data", + "type": { + "type": "nameOnly", + "name": "@supabase/postgrest-js.default.Result" + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "statusText", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "success", + "type": { + "type": "literal", + "value": true + } + } + ] + }, + { + "type": "object", + "name": "PostgrestResponseFailure", + "properties": [ + { + "name": "count", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "PostgrestError" + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "statusText", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "success", + "type": { + "type": "literal", + "value": false + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult1" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is resolved." + } + }, + { + "name": "onrejected", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "reason", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult2" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is rejected." + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PromiseLike" + } + }, + "comment": { + "shortText": "Attaches callbacks for the resolution and/or rejection of the Promise." + } + }, + "@supabase/postgrest-js.PostgrestFilterBuilder.throwOnError": { + "name": "@supabase/postgrest-js.PostgrestFilterBuilder.throwOnError", + "params": [], + "comment": { + "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.\n\nhttps://github.com/supabase/supabase-js/issues/92" + } + }, + "@supabase/postgrest-js.PostgrestQueryBuilder.constructor": { + "name": "@supabase/postgrest-js.PostgrestQueryBuilder.constructor", + "params": [ + { + "name": "url", + "type": { + "type": "nameOnly", + "name": "URL" + }, + "comment": { + "shortText": "The URL for the query" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "URL" + }, + { + "type": "nameOnly", + "name": "RequestInfo" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true, + "comment": { + "shortText": "Custom fetch implementation" + } + }, + { + "name": "headers", + "type": { + "type": "nameOnly", + "name": "HeadersInit" + }, + "isOptional": true, + "comment": { + "shortText": "Custom headers" + } + }, + { + "name": "retry", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Enable automatic retries for transient errors (default: true)" + } + }, + { + "name": "schema", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Postgres schema to use" + } + }, + { + "name": "urlLengthLimit", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "Maximum URL length before warning" + } + } + ] + }, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestQueryBuilder" + } + }, + "comment": { + "shortText": "Creates a query builder scoped to a Postgres table or view.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst { data, error } = await supabase.from('users').select('*')\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport { PostgrestQueryBuilder } from '@supabase/postgrest-js'\n\nconst query = new PostgrestQueryBuilder(\n new URL('https://xyzcompany.supabase.co/rest/v1/users'),\n { headers: { apikey: 'your-publishable-key' }, retry: true }\n)\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestQueryBuilder.delete": { + "name": "@supabase/postgrest-js.PostgrestQueryBuilder.delete", + "params": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "count", + "type": { + "type": "union", + "subTypes": [ + null, + { + "type": "literal", + "value": "exact" + }, + { + "type": "literal", + "value": "planned" + }, + { + "type": "literal", + "value": "estimated" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Count algorithm to use to count deleted rows.\n\n`\"exact\"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the\nhood.\n\n`\"planned\"`: Approximated but fast count algorithm. Uses the Postgres\nstatistics under the hood.\n\n`\"estimated\"`: Uses exact count for low numbers and planned count for high\nnumbers." + } + } + ] + }, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Perform a DELETE on the table or view.\n\nBy default, deleted rows are not returned. To return it, chain the call\nwith `.select()` after filters.", + "text": "- `delete()` should always be combined with [filters](/docs/reference/javascript/using-filters) to target the item(s) you wish to delete.\n- If you use `delete()` with filters and you have\n [RLS](/docs/learn/auth-deep-dive/auth-row-level-security) enabled, only\n rows visible through `SELECT` policies are deleted. Note that by default\n no rows are visible, so you need at least one `SELECT`/`ALL` policy that\n makes the rows visible.\n- When using `delete().in()`, specify an array of values to target multiple rows with a single query. This is particularly useful for batch deleting entries that share common criteria, such as deleting users by their IDs. Ensure that the array you provide accurately represents all records you intend to delete to avoid unintended data removal.", + "examples": [ + { + "id": "delete-a-single-record", + "name": "Delete a single record", + "code": "```ts\nconst response = await supabase\n .from('countries')\n .delete()\n .eq('id', 1)\n```", + "data": { + "sql": "```sql\ncreate table\n countries (id int8 primary key, name text);\n\ninsert into\n countries (id, name)\nvalues\n (1, 'Mordor');\n```" + }, + "response": "```json\n{\n \"status\": 204,\n \"statusText\": \"No Content\"\n}\n```" + }, + { + "id": "handling-errors", + "name": "Handling errors", + "code": "```js\nconst { error } = await supabase.from('countries').delete().eq('id', 1)\nif (error) console.error(error)\n```", + "description": "`error.hint` from Postgres often contains the actionable fix (e.g. `\"Grant the required privileges to the current role with: GRANT DELETE ON public.countries TO anon;\"` for a `42501` permission-denied error). Log the full `error` object so it isn't hidden behind `error.message`." + }, + { + "id": "delete-a-record-and-return-it", + "name": "Delete a record and return it", + "code": "```ts\nconst { data, error } = await supabase\n .from('countries')\n .delete()\n .eq('id', 1)\n .select()\n```", + "data": { + "sql": "```sql\ncreate table\n countries (id int8 primary key, name text);\n\ninsert into\n countries (id, name)\nvalues\n (1, 'Mordor');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Mordor\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "delete-multiple-records", + "name": "Delete multiple records", + "code": "```ts\nconst response = await supabase\n .from('countries')\n .delete()\n .in('id', [1, 2, 3])\n```", + "data": { + "sql": "```sql\ncreate table\n countries (id int8 primary key, name text);\n\ninsert into\n countries (id, name)\nvalues\n (1, 'Rohan'), (2, 'The Shire'), (3, 'Mordor');\n```" + }, + "response": "```json\n{\n \"status\": 204,\n \"statusText\": \"No Content\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestQueryBuilder.insert": { + "name": "@supabase/postgrest-js.PostgrestQueryBuilder.insert", + "params": [ + { + "name": "values", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RejectExcessProperties" + }, + { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "RejectExcessProperties" + } + } + ] + }, + "comment": { + "shortText": "The values to insert. Pass an object to insert a single row\nor an array to insert multiple rows." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "count", + "type": { + "type": "union", + "subTypes": [ + null, + { + "type": "literal", + "value": "exact" + }, + { + "type": "literal", + "value": "planned" + }, + { + "type": "literal", + "value": "estimated" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Count algorithm to use to count inserted rows.\n\n`\"exact\"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the\nhood.\n\n`\"planned\"`: Approximated but fast count algorithm. Uses the Postgres\nstatistics under the hood.\n\n`\"estimated\"`: Uses exact count for low numbers and planned count for high\nnumbers." + } + }, + { + "name": "defaultToNull", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Make missing fields default to `null`.\nOtherwise, use the default value for the column. Only applies for bulk\ninserts." + } + } + ] + }, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Perform an INSERT into the table or view.\n\nBy default, inserted rows are not returned. To return it, chain the call\nwith `.select()`.", + "examples": [ + { + "id": "create-a-record", + "name": "Create a record", + "code": "```ts\nconst { error } = await supabase\n .from('countries')\n .insert({ id: 1, name: 'Mordor' })\n```", + "data": { + "sql": "```sql\ncreate table\n countries (id int8 primary key, name text);\n```" + }, + "response": "```json\n{\n \"status\": 201,\n \"statusText\": \"Created\"\n}\n```" + }, + { + "id": "handling-errors", + "name": "Handling errors", + "code": "```js\nconst { error } = await supabase.from('countries').insert({ id: 1, name: 'Mordor' })\nif (error) console.error(error)\n```", + "description": "`error.hint` from Postgres often contains the actionable fix (e.g. `\"Grant the required privileges to the current role with: GRANT INSERT ON public.countries TO anon;\"` for a `42501` permission-denied error). Log the full `error` object so it isn't hidden behind `error.message`." + }, + { + "id": "create-a-record-and-return-it", + "name": "Create a record and return it", + "code": "```ts\nconst { data, error } = await supabase\n .from('countries')\n .insert({ id: 1, name: 'Mordor' })\n .select()\n```", + "data": { + "sql": "```sql\ncreate table\n countries (id int8 primary key, name text);\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Mordor\"\n }\n ],\n \"status\": 201,\n \"statusText\": \"Created\"\n}\n```" + }, + { + "id": "bulk-create", + "name": "Bulk create", + "code": "```ts\nconst { error } = await supabase\n .from('countries')\n .insert([\n { id: 1, name: 'Mordor' },\n { id: 1, name: 'The Shire' },\n ])\n```", + "description": "A bulk create operation is handled in a single transaction.\nIf any of the inserts fail, none of the rows are inserted.", + "data": { + "sql": "```sql\ncreate table\n countries (id int8 primary key, name text);\n```" + }, + "response": "```json\n{\n \"error\": {\n \"code\": \"23505\",\n \"details\": \"Key (id)=(1) already exists.\",\n \"hint\": null,\n \"message\": \"duplicate key value violates unique constraint \\\"countries_pkey\\\"\"\n },\n \"status\": 409,\n \"statusText\": \"Conflict\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestQueryBuilder.select": { + "name": "@supabase/postgrest-js.PostgrestQueryBuilder.select", + "params": [ + { + "name": "columns", + "type": { + "type": "nameOnly", + "name": "Query" + }, + "isOptional": true, + "comment": { + "shortText": "The columns to retrieve, separated by commas. Columns can be renamed when returned with `customName:columnName`" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "count", + "type": { + "type": "union", + "subTypes": [ + null, + { + "type": "literal", + "value": "exact" + }, + { + "type": "literal", + "value": "planned" + }, + { + "type": "literal", + "value": "estimated" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Count algorithm to use to count rows in the table or view.\n\n`\"exact\"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the\nhood.\n\n`\"planned\"`: Approximated but fast count algorithm. Uses the Postgres\nstatistics under the hood.\n\n`\"estimated\"`: Uses exact count for low numbers and planned count for high\nnumbers." + } + }, + { + "name": "head", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "When set to `true`, `data` will not be returned.\nUseful if you only need the count." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Perform a SELECT query on the table or view.", + "text": "When using `count` with `.range()` or `.limit()`, the returned `count` is the total number of rows\nthat match your filters, not the number of rows in the current page. Use this to build pagination UI.\n\n- By default, Supabase projects return a maximum of 1,000 rows. This setting can be changed in your project's [API settings](/dashboard/project/_/settings/api). It's recommended that you keep it low to limit the payload size of accidental or malicious requests. You can use `range()` queries to paginate through your data.\n- `select()` can be combined with [Filters](/docs/reference/javascript/using-filters)\n- `select()` can be combined with [Modifiers](/docs/reference/javascript/using-modifiers)\n- `apikey` is a reserved keyword if you're using the [Supabase Platform](/docs/guides/platform) and [should be avoided as a column name](https://github.com/supabase/supabase/issues/5465). *", + "examples": [ + { + "id": "getting-your-data", + "name": "Getting your data", + "code": "```js\nconst { data, error } = await supabase\n .from('characters')\n .select()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Harry'),\n (2, 'Frodo'),\n (3, 'Katniss');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Harry\"\n },\n {\n \"id\": 2,\n \"name\": \"Frodo\"\n },\n {\n \"id\": 3,\n \"name\": \"Katniss\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "handling-errors", + "name": "Handling errors", + "code": "```js\nconst { data, error } = await supabase.from('characters').select()\nif (error) {\n // Logs the full error: message, code, details, and hint.\n console.error(error)\n return\n}\n```", + "description": "The most useful field on a Postgres error is usually `hint` — when the database knows the fix, it puts the literal SQL there. For example, a permission-denied error (`code: '42501'`) arrives with a `hint` like `\"Grant the required privileges to the current role with: GRANT SELECT ON public.characters TO anon;\"`. Log the full `error` object so the hint isn't hidden behind `error.message`.", + "response": "```json\n{\n \"error\": {\n \"code\": \"42501\",\n \"details\": null,\n \"hint\": \"Grant the required privileges to the current role with: GRANT SELECT ON public.characters TO anon;\",\n \"message\": \"permission denied for table characters\"\n },\n \"status\": 401,\n \"statusText\": \"Unauthorized\"\n}\n```" + }, + { + "id": "selecting-specific-columns", + "name": "Selecting specific columns", + "code": "```js\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Frodo'),\n (2, 'Harry'),\n (3, 'Katniss');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Frodo\"\n },\n {\n \"name\": \"Harry\"\n },\n {\n \"name\": \"Katniss\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "query-referenced-tables", + "name": "Query referenced tables", + "code": "```js\nconst { data, error } = await supabase\n .from('orchestral_sections')\n .select(`\n name,\n instruments (\n name\n )\n `)\n```", + "description": "If your database has foreign key relationships, you can query related tables too.", + "data": { + "sql": "```sql\ncreate table\n orchestral_sections (id int8 primary key, name text);\ncreate table\n instruments (\n id int8 primary key,\n section_id int8 not null references orchestral_sections,\n name text\n );\n\ninsert into\n orchestral_sections (id, name)\nvalues\n (1, 'strings'),\n (2, 'woodwinds');\ninsert into\n instruments (id, section_id, name)\nvalues\n (1, 2, 'flute'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"strings\",\n \"instruments\": [\n {\n \"name\": \"violin\"\n }\n ]\n },\n {\n \"name\": \"woodwinds\",\n \"instruments\": [\n {\n \"name\": \"flute\"\n }\n ]\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "query-referenced-tables-with-spaces-in-their-names", + "name": "Query referenced tables with spaces in their names", + "code": "```js\nconst { data, error } = await supabase\n .from('orchestral sections')\n .select(`\n name,\n \"musical instruments\" (\n name\n )\n `)\n```", + "description": "If your table name contains spaces, you must use double quotes in the `select` statement to reference the table.", + "data": { + "sql": "```sql\ncreate table\n \"orchestral sections\" (id int8 primary key, name text);\ncreate table\n \"musical instruments\" (\n id int8 primary key,\n section_id int8 not null references \"orchestral sections\",\n name text\n );\n\ninsert into\n \"orchestral sections\" (id, name)\nvalues\n (1, 'strings'),\n (2, 'woodwinds');\ninsert into\n \"musical instruments\" (id, section_id, name)\nvalues\n (1, 2, 'flute'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"strings\",\n \"musical instruments\": [\n {\n \"name\": \"violin\"\n }\n ]\n },\n {\n \"name\": \"woodwinds\",\n \"musical instruments\": [\n {\n \"name\": \"flute\"\n }\n ]\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "query-referenced-tables-through-a-join-table", + "name": "Query referenced tables through a join table", + "code": "```ts\nconst { data, error } = await supabase\n .from('users')\n .select(`\n name,\n teams (\n name\n )\n `)\n \n```", + "description": "If you're in a situation where your tables are **NOT** directly\nrelated, but instead are joined by a _join table_, you can still use\nthe `select()` method to query the related data. The join table needs\nto have the foreign keys as part of its composite primary key.", + "data": { + "sql": "```sql\ncreate table\n users (\n id int8 primary key,\n name text\n );\ncreate table\n teams (\n id int8 primary key,\n name text\n );\n-- join table\ncreate table\n users_teams (\n user_id int8 not null references users,\n team_id int8 not null references teams,\n -- both foreign keys must be part of a composite primary key\n primary key (user_id, team_id)\n );\n\ninsert into\n users (id, name)\nvalues\n (1, 'Kiran'),\n (2, 'Evan');\ninsert into\n teams (id, name)\nvalues\n (1, 'Green'),\n (2, 'Blue');\ninsert into\n users_teams (user_id, team_id)\nvalues\n (1, 1),\n (1, 2),\n (2, 2);\n```" + }, + "response": "```json\n {\n \"data\": [\n {\n \"name\": \"Kiran\",\n \"teams\": [\n {\n \"name\": \"Green\"\n },\n {\n \"name\": \"Blue\"\n }\n ]\n },\n {\n \"name\": \"Evan\",\n \"teams\": [\n {\n \"name\": \"Blue\"\n }\n ]\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n }\n \n```" + }, + { + "id": "query-the-same-referenced-table-multiple-times", + "name": "Query the same referenced table multiple times", + "code": "```ts\nconst { data, error } = await supabase\n .from('messages')\n .select(`\n content,\n from:sender_id(name),\n to:receiver_id(name)\n `)\n\n// To infer types, use the name of the table (in this case `users`) and\n// the name of the foreign key constraint.\nconst { data, error } = await supabase\n .from('messages')\n .select(`\n content,\n from:users!messages_sender_id_fkey(name),\n to:users!messages_receiver_id_fkey(name)\n `)\n```", + "description": "If you need to query the same referenced table twice, use the name of the\njoined column to identify which join to use. You can also give each\ncolumn an alias.", + "data": { + "sql": "```sql\n create table\n users (id int8 primary key, name text);\n\n create table\n messages (\n sender_id int8 not null references users,\n receiver_id int8 not null references users,\n content text\n );\n\n insert into\n users (id, name)\n values\n (1, 'Kiran'),\n (2, 'Evan');\n\n insert into\n messages (sender_id, receiver_id, content)\n values\n (1, 2, '👋');\n ```\n```\n\n@exampleResponse Query the same referenced table multiple times\n```json\n{\n \"data\": [\n {\n \"content\": \"👋\",\n \"from\": {\n \"name\": \"Kiran\"\n },\n \"to\": {\n \"name\": \"Evan\"\n }\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```\n\n@exampleDescription Query nested foreign tables through a join table\nYou can use the result of a joined table to gather data in\nanother foreign table. With multiple references to the same foreign\ntable you must specify the column on which to conduct the join.\n\n@example Query nested foreign tables through a join table\n```ts\n const { data, error } = await supabase\n .from('games')\n .select(`\n game_id:id,\n away_team:teams!games_away_team_fkey (\n users (\n id,\n name\n )\n )\n `)\n \n```\n\n@exampleSql Query nested foreign tables through a join table\n```sql\n```sql\ncreate table\n users (\n id int8 primary key,\n name text\n );\ncreate table\n teams (\n id int8 primary key,\n name text\n );\n-- join table\ncreate table\n users_teams (\n user_id int8 not null references users,\n team_id int8 not null references teams,\n\n primary key (user_id, team_id)\n );\ncreate table\n games (\n id int8 primary key,\n home_team int8 not null references teams,\n away_team int8 not null references teams,\n name text\n );\n\ninsert into users (id, name)\nvalues\n (1, 'Kiran'),\n (2, 'Evan');\ninsert into\n teams (id, name)\nvalues\n (1, 'Green'),\n (2, 'Blue');\ninsert into\n users_teams (user_id, team_id)\nvalues\n (1, 1),\n (1, 2),\n (2, 2);\ninsert into\n games (id, home_team, away_team, name)\nvalues\n (1, 1, 2, 'Green vs Blue'),\n (2, 2, 1, 'Blue vs Green');\n```" + } + }, + { + "id": "filtering-through-referenced-tables", + "name": "Filtering through referenced tables", + "code": "```ts\nconst { data, error } = await supabase\n .from('instruments')\n .select('name, orchestral_sections(*)')\n .eq('orchestral_sections.name', 'percussion')\n```", + "description": "If the filter on a referenced table's column is not satisfied, the referenced\ntable returns `[]` or `null` but the parent table is not filtered out.\nIf you want to filter out the parent table rows, use the `!inner` hint", + "data": { + "sql": "```sql\ncreate table\n orchestral_sections (id int8 primary key, name text);\ncreate table\n instruments (\n id int8 primary key,\n section_id int8 not null references orchestral_sections,\n name text\n );\n\ninsert into\n orchestral_sections (id, name)\nvalues\n (1, 'strings'),\n (2, 'woodwinds');\ninsert into\n instruments (id, section_id, name)\nvalues\n (1, 2, 'flute'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"flute\",\n \"orchestral_sections\": null\n },\n {\n \"name\": \"violin\",\n \"orchestral_sections\": null\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "querying-referenced-table-with-count", + "name": "Querying referenced table with count", + "code": "```ts\nconst { data, error } = await supabase\n .from('orchestral_sections')\n .select(`*, instruments(count)`)\n```", + "description": "You can get the number of rows in a related table by using the\n**count** property.", + "data": { + "sql": "```sql\ncreate table orchestral_sections (\n \"id\" \"uuid\" primary key default \"extensions\".\"uuid_generate_v4\"() not null,\n \"name\" text\n);\n\ncreate table characters (\n \"id\" \"uuid\" primary key default \"extensions\".\"uuid_generate_v4\"() not null,\n \"name\" text,\n \"section_id\" \"uuid\" references public.orchestral_sections on delete cascade\n);\n\nwith section as (\n insert into orchestral_sections (name)\n values ('strings') returning id\n)\ninsert into instruments (name, section_id) values\n('violin', (select id from section)),\n('viola', (select id from section)),\n('cello', (select id from section)),\n('double bass', (select id from section));\n```" + }, + "response": "```json\n[\n {\n \"id\": \"693694e7-d993-4360-a6d7-6294e325d9b6\",\n \"name\": \"strings\",\n \"instruments\": [\n {\n \"count\": 4\n }\n ]\n }\n]\n```" + }, + { + "id": "querying-with-count-option", + "name": "Querying with count option", + "code": "```ts\nconst { count, error } = await supabase\n .from('characters')\n .select('*', { count: 'exact', head: true })\n```", + "description": "You can get the number of rows by using the\n[count](/docs/reference/javascript/select#parameters) option.", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"count\": 3,\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "querying-json-data", + "name": "Querying JSON data", + "code": "```ts\nconst { data, error } = await supabase\n .from('users')\n .select(`\n id, name,\n address->city\n `)\n```", + "description": "You can select and filter data inside of\n[JSON](/docs/guides/database/json) columns. Postgres offers some\n[operators](/docs/guides/database/json#query-the-jsonb-data) for\nquerying JSON data.", + "data": { + "sql": "```sql\ncreate table\n users (\n id int8 primary key,\n name text,\n address jsonb\n );\n\ninsert into\n users (id, name, address)\nvalues\n (1, 'Frodo', '{\"city\":\"Hobbiton\"}');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Frodo\",\n \"city\": \"Hobbiton\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "querying-referenced-table-with-inner-join", + "name": "Querying referenced table with inner join", + "code": "```ts\nconst { data, error } = await supabase\n .from('instruments')\n .select('name, orchestral_sections!inner(name)')\n .eq('orchestral_sections.name', 'woodwinds')\n .limit(1)\n```", + "description": "If you don't want to return the referenced table contents, you can leave the parenthesis empty.\nLike `.select('name, orchestral_sections!inner()')`.", + "data": { + "sql": "```sql\ncreate table orchestral_sections (\n \"id\" \"uuid\" primary key default \"extensions\".\"uuid_generate_v4\"() not null,\n \"name\" text\n);\n\ncreate table instruments (\n \"id\" \"uuid\" primary key default \"extensions\".\"uuid_generate_v4\"() not null,\n \"name\" text,\n \"section_id\" \"uuid\" references public.orchestral_sections on delete cascade\n);\n\nwith section as (\n insert into orchestral_sections (name)\n values ('woodwinds') returning id\n)\ninsert into instruments (name, section_id) values\n('flute', (select id from section)),\n('clarinet', (select id from section)),\n('bassoon', (select id from section)),\n('piccolo', (select id from section));\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"flute\",\n \"orchestral_sections\": {\"name\": \"woodwinds\"}\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "switching-schemas-per-query", + "name": "Switching schemas per query", + "code": "```ts\nconst { data, error } = await supabase\n .schema('myschema')\n .from('mytable')\n .select()\n```", + "description": "In addition to setting the schema during initialization, you can also switch schemas on a per-query basis.\nMake sure you've set up your [database privileges and API settings](/docs/guides/api/using-custom-schemas).", + "data": { + "sql": "```sql\ncreate schema myschema;\n\ncreate table myschema.mytable (\n id uuid primary key default gen_random_uuid(),\n data text\n);\n\ninsert into myschema.mytable (data) values ('mydata');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": \"4162e008-27b0-4c0f-82dc-ccaeee9a624d\",\n \"data\": \"mydata\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestQueryBuilder.update": { + "name": "@supabase/postgrest-js.PostgrestQueryBuilder.update", + "params": [ + { + "name": "values", + "type": { + "type": "nameOnly", + "name": "RejectExcessProperties" + }, + "comment": { + "shortText": "The values to update with" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "count", + "type": { + "type": "union", + "subTypes": [ + null, + { + "type": "literal", + "value": "exact" + }, + { + "type": "literal", + "value": "planned" + }, + { + "type": "literal", + "value": "estimated" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Count algorithm to use to count updated rows.\n\n`\"exact\"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the\nhood.\n\n`\"planned\"`: Approximated but fast count algorithm. Uses the Postgres\nstatistics under the hood.\n\n`\"estimated\"`: Uses exact count for low numbers and planned count for high\nnumbers." + } + } + ] + }, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Perform an UPDATE on the table or view.\n\nBy default, updated rows are not returned. To return it, chain the call\nwith `.select()` after filters.", + "text": "- `update()` should always be combined with [Filters](/docs/reference/javascript/using-filters) to target the item(s) you wish to update.", + "examples": [ + { + "id": "updating-your-data", + "name": "Updating your data", + "code": "```ts\nconst { error } = await supabase\n .from('instruments')\n .update({ name: 'piano' })\n .eq('id', 1)\n```", + "data": { + "sql": "```sql\ncreate table\n instruments (id int8 primary key, name text);\n\ninsert into\n instruments (id, name)\nvalues\n (1, 'harpsichord');\n```" + }, + "response": "```json\n{\n \"status\": 204,\n \"statusText\": \"No Content\"\n}\n```" + }, + { + "id": "handling-errors", + "name": "Handling errors", + "code": "```js\nconst { error } = await supabase.from('instruments').update({ name: 'piano' }).eq('id', 1)\nif (error) console.error(error)\n```", + "description": "`error.hint` from Postgres often contains the actionable fix (e.g. `\"Grant the required privileges to the current role with: GRANT UPDATE ON public.instruments TO anon;\"` for a `42501` permission-denied error). Log the full `error` object so it isn't hidden behind `error.message`." + }, + { + "id": "update-a-record-and-return-it", + "name": "Update a record and return it", + "code": "```ts\nconst { data, error } = await supabase\n .from('instruments')\n .update({ name: 'piano' })\n .eq('id', 1)\n .select()\n```", + "data": { + "sql": "```sql\ncreate table\n instruments (id int8 primary key, name text);\n\ninsert into\n instruments (id, name)\nvalues\n (1, 'harpsichord');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"piano\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "updating-json-data", + "name": "Updating JSON data", + "code": "```ts\nconst { data, error } = await supabase\n .from('users')\n .update({\n address: {\n street: 'Melrose Place',\n postcode: 90210\n }\n })\n .eq('address->postcode', 90210)\n .select()\n```", + "description": "Postgres offers some\n[operators](/docs/guides/database/json#query-the-jsonb-data) for\nworking with JSON data. Currently, it is only possible to update the entire JSON document.", + "data": { + "sql": "```sql\ncreate table\n users (\n id int8 primary key,\n name text,\n address jsonb\n );\n\ninsert into\n users (id, name, address)\nvalues\n (1, 'Michael', '{ \"postcode\": 90210 }');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Michael\",\n \"address\": {\n \"street\": \"Melrose Place\",\n \"postcode\": 90210\n }\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestQueryBuilder.upsert": { + "name": "@supabase/postgrest-js.PostgrestQueryBuilder.upsert", + "params": [ + { + "name": "values", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RejectExcessProperties" + }, + { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "RejectExcessProperties" + } + } + ] + }, + "comment": { + "shortText": "The values to upsert with. Pass an object to upsert a\nsingle row or an array to upsert multiple rows." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "count", + "type": { + "type": "union", + "subTypes": [ + null, + { + "type": "literal", + "value": "exact" + }, + { + "type": "literal", + "value": "planned" + }, + { + "type": "literal", + "value": "estimated" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Count algorithm to use to count upserted rows.\n\n`\"exact\"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the\nhood.\n\n`\"planned\"`: Approximated but fast count algorithm. Uses the Postgres\nstatistics under the hood.\n\n`\"estimated\"`: Uses exact count for low numbers and planned count for high\nnumbers." + } + }, + { + "name": "defaultToNull", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Make missing fields default to `null`.\nOtherwise, use the default value for the column. This only applies when\ninserting new rows, not when merging with existing rows under\n`ignoreDuplicates: false`. This also only applies when doing bulk upserts." + } + }, + { + "name": "ignoreDuplicates", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, duplicate rows are ignored. If\n`false`, duplicate rows are merged with existing rows." + } + }, + { + "name": "onConflict", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Comma-separated UNIQUE column(s) to specify how\nduplicate rows are determined. Two rows are duplicates if all the\n`onConflict` columns are equal." + } + } + ] + }, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Perform an UPSERT on the table or view. Depending on the column(s) passed\nto `onConflict`, `.upsert()` allows you to perform the equivalent of\n`.insert()` if a row with the corresponding `onConflict` columns doesn't\nexist, or if it does exist, perform an alternative action depending on\n`ignoreDuplicates`.\n\nBy default, upserted rows are not returned. To return it, chain the call\nwith `.select()`.", + "text": "- Primary keys must be included in `values` to use upsert.", + "examples": [ + { + "id": "upsert-a-single-row-using-a-unique-key", + "name": "Upsert a single row using a unique key", + "code": "```ts\n// Upserting a single row, overwriting based on the 'username' unique column\nconst { data, error } = await supabase\n .from('users')\n .upsert({ username: 'supabot' }, { onConflict: 'username' })\n\n// Example response:\n// {\n// data: [\n// { id: 4, message: 'bar', username: 'supabot' }\n// ],\n// error: null\n// }\n```" + }, + { + "id": "upsert-with-conflict-resolution-and-exact-row-counting", + "name": "Upsert with conflict resolution and exact row counting", + "code": "```ts\n// Upserting and returning exact count\nconst { data, error, count } = await supabase\n .from('users')\n .upsert(\n {\n id: 3,\n message: 'foo',\n username: 'supabot'\n },\n {\n onConflict: 'username',\n count: 'exact'\n }\n )\n\n// Example response:\n// {\n// data: [\n// {\n// id: 42,\n// handle: \"saoirse\",\n// display_name: \"Saoirse\"\n// }\n// ],\n// count: 1,\n// error: null\n// }\n```" + }, + { + "id": "upsert-your-data", + "name": "Upsert your data", + "code": "```ts\nconst { data, error } = await supabase\n .from('instruments')\n .upsert({ id: 1, name: 'piano' })\n .select()\n```", + "data": { + "sql": "```sql\ncreate table\n instruments (id int8 primary key, name text);\n\ninsert into\n instruments (id, name)\nvalues\n (1, 'harpsichord');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"piano\"\n }\n ],\n \"status\": 201,\n \"statusText\": \"Created\"\n}\n```" + }, + { + "id": "handling-errors", + "name": "Handling errors", + "code": "```js\nconst { data, error } = await supabase.from('instruments').upsert({ id: 1, name: 'piano' }).select()\nif (error) console.error(error)\n```", + "description": "`error.hint` from Postgres often contains the actionable fix (e.g. `\"Grant the required privileges to the current role with: GRANT INSERT, UPDATE ON public.instruments TO anon;\"` for a `42501` permission-denied error). Log the full `error` object so it isn't hidden behind `error.message`." + }, + { + "id": "bulk-upsert-your-data", + "name": "Bulk Upsert your data", + "code": "```ts\nconst { data, error } = await supabase\n .from('instruments')\n .upsert([\n { id: 1, name: 'piano' },\n { id: 2, name: 'harp' },\n ])\n .select()\n```", + "data": { + "sql": "```sql\ncreate table\n instruments (id int8 primary key, name text);\n\ninsert into\n instruments (id, name)\nvalues\n (1, 'harpsichord');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"piano\"\n },\n {\n \"id\": 2,\n \"name\": \"harp\"\n }\n ],\n \"status\": 201,\n \"statusText\": \"Created\"\n}\n```" + }, + { + "id": "upserting-into-tables-with-constraints", + "name": "Upserting into tables with constraints", + "code": "```ts\nconst { data, error } = await supabase\n .from('users')\n .upsert({ id: 42, handle: 'saoirse', display_name: 'Saoirse' })\n .select()\n```", + "description": "In the following query, `upsert()` implicitly uses the `id`\n(primary key) column to determine conflicts. If there is no existing\nrow with the same `id`, `upsert()` inserts a new row, which\nwill fail in this case as there is already a row with `handle` `\"saoirse\"`.\nUsing the `onConflict` option, you can instruct `upsert()` to use\nanother column with a unique constraint to determine conflicts.", + "data": { + "sql": "```sql\ncreate table\n users (\n id int8 generated by default as identity primary key,\n handle text not null unique,\n display_name text\n );\n\ninsert into\n users (id, handle, display_name)\nvalues\n (1, 'saoirse', null);\n```" + }, + "response": "```json\n{\n \"error\": {\n \"code\": \"23505\",\n \"details\": \"Key (handle)=(saoirse) already exists.\",\n \"hint\": null,\n \"message\": \"duplicate key value violates unique constraint \\\"users_handle_key\\\"\"\n },\n \"status\": 409,\n \"statusText\": \"Conflict\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.constructor": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.constructor", + "params": [ + { + "name": "builder", + "type": { + "type": "object", + "properties": [ + { + "name": "body", + "type": { + "type": "intrinsic", + "name": "unknown" + }, + "isOptional": true + }, + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "URL" + }, + { + "type": "nameOnly", + "name": "RequestInfo" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true + }, + { + "name": "headers", + "type": { + "type": "nameOnly", + "name": "HeadersInit" + } + }, + { + "name": "isMaybeSingle", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "method", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "GET" + }, + { + "type": "literal", + "value": "HEAD" + }, + { + "type": "literal", + "value": "POST" + }, + { + "type": "literal", + "value": "PATCH" + }, + { + "type": "literal", + "value": "DELETE" + } + ] + } + }, + { + "name": "retry", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "schema", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "shouldStripNulls", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "shouldThrowOnError", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "isOptional": true + }, + { + "name": "url", + "type": { + "type": "nameOnly", + "name": "URL" + } + }, + { + "name": "urlLengthLimit", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestTransformBuilder" + } + }, + "comment": { + "shortText": "Creates a builder configured for a specific PostgREST request.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst { data, error } = await supabase.from('users').select('*')\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport { PostgrestQueryBuilder } from '@supabase/postgrest-js'\n\nconst builder = new PostgrestQueryBuilder(\n new URL('https://xyzcompany.supabase.co/rest/v1/users'),\n { headers: new Headers({ apikey: 'your-publishable-key' }) }\n)\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.abortSignal": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.abortSignal", + "params": [ + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "comment": { + "shortText": "The AbortSignal to use for the fetch request" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set the AbortSignal for the fetch request.", + "text": "You can use this to set a timeout for the request.", + "examples": [ + { + "id": "aborting-requests-in-flight", + "name": "Aborting requests in-flight", + "code": "```ts\nconst ac = new AbortController()\n\nconst { data, error } = await supabase\n .from('very_big_table')\n .select()\n .abortSignal(ac.signal)\n\n// Abort the request after 100 ms\nsetTimeout(() => ac.abort(), 100)\n```", + "description": "You can use an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) to abort requests.\nNote that `status` and `statusText` don't mean anything for aborted requests as the request wasn't fulfilled.", + "response": "```json\n {\n \"error\": {\n \"message\": \"AbortError: The user aborted a request.\",\n \"details\": \"\",\n \"hint\": \"The request was aborted locally via the provided AbortSignal.\",\n \"code\": \"\"\n },\n \"status\": 0,\n \"statusText\": \"\"\n }\n\n```" + }, + { + "id": "set-a-timeout", + "name": "Set a timeout", + "code": "```ts\nconst { data, error } = await supabase\n .from('very_big_table')\n .select()\n .abortSignal(AbortSignal.timeout(1000 /* ms */))\n```", + "response": "```json\n {\n \"error\": {\n \"message\": \"FetchError: The user aborted a request.\",\n \"details\": \"\",\n \"hint\": \"\",\n \"code\": \"\"\n },\n \"status\": 400,\n \"statusText\": \"Bad Request\"\n }\n\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.csv": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.csv", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Return `data` as a string in CSV format.", + "examples": [ + { + "id": "return-data-as-csv", + "name": "Return data as CSV", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .csv()\n```", + "description": "By default, the data is returned in JSON format, but can also be returned as Comma Separated Values.", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": \"id,name\\n1,Luke\\n2,Leia\\n3,Han\",\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.explain": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.explain", + "params": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "analyze", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, the query will be executed and the\nactual run time will be returned" + } + }, + { + "name": "buffers", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, include information on buffer usage" + } + }, + { + "name": "format", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "text" + }, + { + "type": "literal", + "value": "json" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The format of the output, can be `\"text\"` (default)\nor `\"json\"`" + } + }, + { + "name": "settings", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, include information on configuration\nparameters that affect query planning" + } + }, + { + "name": "verbose", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, the query identifier will be returned\nand `data` will include the output columns of the query" + } + }, + { + "name": "wal", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, include information on WAL record generation" + } + } + ] + }, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "PostgrestBuilder" + }, + { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + ] + } + }, + "comment": { + "shortText": "Return `data` as the EXPLAIN plan for the query.\n\nYou need to enable the\n[db_plan_enabled](https://supabase.com/docs/guides/database/debugging-performance#enabling-explain)\nsetting before using this method.", + "examples": [ + { + "id": "get-the-execution-plan", + "name": "Get the execution plan", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .explain()\n```", + "description": "By default, the data is returned in TEXT format, but can also be returned as JSON by using the `format` parameter.", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```js\nAggregate (cost=33.34..33.36 rows=1 width=112)\n -> Limit (cost=0.00..18.33 rows=1000 width=40)\n -> Seq Scan on characters (cost=0.00..22.00 rows=1200 width=40)\n```" + }, + { + "id": "get-the-execution-plan-with-analyze-and-verbose", + "name": "Get the execution plan with analyze and verbose", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .explain({analyze:true,verbose:true})\n```", + "description": "By default, the data is returned in TEXT format, but can also be returned as JSON by using the `format` parameter.", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```js\nAggregate (cost=33.34..33.36 rows=1 width=112) (actual time=0.041..0.041 rows=1 loops=1)\n Output: NULL::bigint, count(ROW(characters.id, characters.name)), COALESCE(json_agg(ROW(characters.id, characters.name)), '[]'::json), NULLIF(current_setting('response.headers'::text, true), ''::text), NULLIF(current_setting('response.status'::text, true), ''::text)\n -> Limit (cost=0.00..18.33 rows=1000 width=40) (actual time=0.005..0.006 rows=3 loops=1)\n Output: characters.id, characters.name\n -> Seq Scan on public.characters (cost=0.00..22.00 rows=1200 width=40) (actual time=0.004..0.005 rows=3 loops=1)\n Output: characters.id, characters.name\nQuery Identifier: -4730654291623321173\nPlanning Time: 0.407 ms\nExecution Time: 0.119 ms\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.geojson": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.geojson", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Return `data` as an object in [GeoJSON](https://geojson.org) format." + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.limit": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.limit", + "params": [ + { + "name": "rows", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The maximum number of rows to return" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Deprecated, use `options.referencedTable`\ninstead" + } + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Set this to limit rows of referenced\ntables instead of the parent table" + } + } + ] + }, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Limit the query result by `rows`.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .limit(1)\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Luke\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "on-a-referenced-table", + "name": "On a referenced table", + "code": "```ts\nconst { data, error } = await supabase\n .from('orchestral_sections')\n .select(`\n name,\n instruments (\n name\n )\n `)\n .limit(1, { referencedTable: 'instruments' })\n```", + "data": { + "sql": "```sql\ncreate table\n orchestral_sections (id int8 primary key, name text);\ncreate table\n instruments (\n id int8 primary key,\n section_id int8 not null references orchestral_sections,\n name text\n );\n\ninsert into\n orchestral_sections (id, name)\nvalues\n (1, 'strings');\ninsert into\n instruments (id, section_id, name)\nvalues\n (1, 1, 'harp'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"strings\",\n \"instruments\": [\n {\n \"name\": \"violin\"\n }\n ]\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.maxAffected": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.maxAffected", + "params": [ + { + "name": "rows", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The maximum number of rows that can be affected" + } + } + ], + "comment": { + "shortText": "Set the maximum number of rows that can be affected by the query.\nOnly available in PostgREST v13+ and only works with PATCH and DELETE methods." + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.maybeSingle": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.maybeSingle", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Return `data` as a single object instead of an array of objects.\n\nQuery result must be zero or one row (e.g. using `.limit(1)`), otherwise\nthis returns an error.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .eq('name', 'Katniss')\n .maybeSingle()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.order": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.order", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "ascending", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "nullsFirst", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "undefined" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Order the query result by `column`.\n\nYou can call this method multiple times to order by multiple columns.\n\nYou can order referenced tables, but it only affects the ordering of the\nparent table if you use `!inner` in the query.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('id, name')\n .order('id', { ascending: false })\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 3,\n \"name\": \"Han\"\n },\n {\n \"id\": 2,\n \"name\": \"Leia\"\n },\n {\n \"id\": 1,\n \"name\": \"Luke\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "on-a-referenced-table", + "name": "On a referenced table", + "code": "```ts\n const { data, error } = await supabase\n .from('orchestral_sections')\n .select(`\n name,\n instruments (\n name\n )\n `)\n .order('name', { referencedTable: 'instruments', ascending: false })\n\n```", + "description": "Ordering with `referencedTable` doesn't affect the ordering of the\nparent table.", + "data": { + "sql": "```sql\ncreate table\n orchestral_sections (id int8 primary key, name text);\ncreate table\n instruments (\n id int8 primary key,\n section_id int8 not null references orchestral_sections,\n name text\n );\n\ninsert into\n orchestral_sections (id, name)\nvalues\n (1, 'strings'),\n (2, 'woodwinds');\ninsert into\n instruments (id, section_id, name)\nvalues\n (1, 1, 'harp'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"strings\",\n \"instruments\": [\n {\n \"name\": \"violin\"\n },\n {\n \"name\": \"harp\"\n }\n ]\n },\n {\n \"name\": \"woodwinds\",\n \"instruments\": []\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "order-parent-table-by-a-referenced-table", + "name": "Order parent table by a referenced table", + "code": "```ts\n const { data, error } = await supabase\n .from('instruments')\n .select(`\n name,\n section:orchestral_sections (\n name\n )\n `)\n .order('section(name)', { ascending: true })\n\n```", + "description": "Ordering with `referenced_table(col)` affects the ordering of the\nparent table.", + "data": { + "sql": "```sql\ncreate table\n orchestral_sections (id int8 primary key, name text);\ncreate table\n instruments (\n id int8 primary key,\n section_id int8 not null references orchestral_sections,\n name text\n );\n\ninsert into\n orchestral_sections (id, name)\nvalues\n (1, 'strings'),\n (2, 'woodwinds');\ninsert into\n instruments (id, section_id, name)\nvalues\n (1, 2, 'flute'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"violin\",\n \"orchestral_sections\": {\"name\": \"strings\"}\n },\n {\n \"name\": \"flute\",\n \"orchestral_sections\": {\"name\": \"woodwinds\"}\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "ascending", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "nullsFirst", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + }, + { + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "ascending", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "undefined" + }, + "isOptional": true + }, + { + "name": "nullsFirst", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + }, + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "ascending", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "nullsFirst", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.overrideTypes": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.overrideTypes", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Override the type of the returned `data` field in the response.", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```typescript\n// Merge with existing types (default behavior)\nconst query = supabase\n .from('users')\n .select()\n .overrideTypes<{ custom_field: string }>()\n\n// Replace existing types completely\nconst replaceQuery = supabase\n .from('users')\n .select()\n .overrideTypes<{ id: number; name: string }, { merge: false }>()\n```" + }, + { + "id": "complete-override-type-of-successful-response", + "name": "Complete Override type of successful response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .overrideTypes, { merge: false }>()\n```", + "response": "```ts\nlet x: typeof data // MyType[]\n```" + }, + { + "id": "complete-override-type-of-object-response", + "name": "Complete Override type of object response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .maybeSingle()\n .overrideTypes()\n```", + "response": "```ts\nlet x: typeof data // MyType | null\n```" + }, + { + "id": "partial-override-type-of-successful-response", + "name": "Partial Override type of successful response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .overrideTypes>()\n```", + "response": "```ts\nlet x: typeof data // Array\n```" + }, + { + "id": "partial-override-type-of-object-response", + "name": "Partial Override type of object response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .maybeSingle()\n .overrideTypes<{ status: \"A\" | \"B\" }>()\n```", + "response": "```ts\nlet x: typeof data // CountryRowProperties & { status: \"A\" | \"B\" } | null\n```" + }, + { + "id": "merge-vs-replace-existing-types", + "name": "Merge vs replace existing types", + "code": "```typescript\n// Merge with existing types (default behavior)\nconst query = supabase\n .from('users')\n .select()\n .overrideTypes<{ custom_field: string }>()\n\n// Replace existing types completely\nconst replaceQuery = supabase\n .from('users')\n .select()\n .overrideTypes<{ id: number; name: string }, { merge: false }>()\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.range": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.range", + "params": [ + { + "name": "from", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The starting index from which to limit the result" + } + }, + { + "name": "to", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The last index to which to limit the result" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Deprecated, use `options.referencedTable`\ninstead" + } + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Set this to limit rows of referenced\ntables instead of the parent table" + } + } + ] + }, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Limit the query result by starting at an offset `from` and ending at the offset `to`.\nOnly records within this range are returned.\nThis respects the query order and if there is no order clause the range could behave unexpectedly.\nThe `from` and `to` values are 0-based and inclusive: `range(1, 3)` will include the second, third\nand fourth rows of the query.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .range(0, 1)\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Luke\"\n },\n {\n \"name\": \"Leia\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.retry": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.retry", + "params": [ + { + "name": "enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "comment": { + "shortText": "Whether to enable retries for this request" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\n// Disable retries for a specific query\nconst { data, error } = await supabase\n .from('users')\n .select()\n .retry(false)\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.returns": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.returns", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestTransformBuilder" + } + }, + "comment": { + "shortText": "Override the type of the returned `data`.", + "text": "- Deprecated: use overrideTypes method instead", + "examples": [ + { + "id": "override-type-of-successful-response", + "name": "Override type of successful response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .returns>()\n```", + "response": "```js\nlet x: typeof data // MyType[]\n```" + }, + { + "id": "override-type-of-object-response", + "name": "Override type of object response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .maybeSingle()\n .returns()\n```", + "response": "```js\nlet x: typeof data // MyType | null\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.rollback": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.rollback", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Rollback the query.\n\n`data` will still be returned, but the query is not committed." + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.select": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.select", + "params": [ + { + "name": "columns", + "type": { + "type": "nameOnly", + "name": "Query" + }, + "isOptional": true, + "comment": { + "shortText": "The columns to retrieve, separated by commas" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Perform a SELECT on the query result.\n\nBy default, `.insert()`, `.update()`, `.upsert()`, and `.delete()` do not\nreturn modified rows. By calling this method, modified rows are returned in\n`data`.", + "examples": [ + { + "id": "with-upsert", + "name": "With `upsert()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .upsert({ id: 1, name: 'Han Solo' })\n .select()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Han Solo\"\n }\n ],\n \"status\": 201,\n \"statusText\": \"Created\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.setHeader": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.setHeader", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set an HTTP header for the request." + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.single": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.single", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Return `data` as a single object instead of an array of objects.\n\nQuery result must be one row (e.g. using `.limit(1)`), otherwise this\nreturns an error.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .limit(1)\n .single()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": {\n \"name\": \"Luke\"\n },\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.stripNulls": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.stripNulls", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Strip null values from the response data. Properties with `null` values\nwill be omitted from the returned JSON objects.\n\nRequires PostgREST 11.2.0+.\n\nhttps://docs.postgrest.org/en/stable/references/api/resource_representation.html#stripped-nulls", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .stripNulls()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text, bio text);\n\ninsert into\n characters (id, name, bio)\nvalues\n (1, 'Luke', null),\n (2, 'Leia', 'Princess of Alderaan');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Luke\"\n },\n {\n \"id\": 2,\n \"name\": \"Leia\",\n \"bio\": \"Princess of Alderaan\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.then": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.then", + "params": [ + { + "name": "onfulfilled", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "value", + "type": { + "type": "union", + "name": "PostgrestSingleResponse", + "subTypes": [ + { + "type": "object", + "name": "PostgrestResponseSuccess", + "properties": [ + { + "name": "count", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + } + }, + { + "name": "data", + "type": { + "type": "nameOnly", + "name": "@supabase/postgrest-js.default.Result" + } + }, + { + "name": "error", + "type": "[Circular]" + }, + { + "name": "status", + "type": "[Circular]" + }, + { + "name": "statusText", + "type": "[Circular]" + }, + { + "name": "success", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "name": "PostgrestResponseFailure", + "properties": [ + { + "name": "count", + "type": "[Circular]" + }, + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "PostgrestError" + } + }, + { + "name": "status", + "type": "[Circular]" + }, + { + "name": "statusText", + "type": "[Circular]" + }, + { + "name": "success", + "type": "[Circular]" + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult1" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is resolved." + } + }, + { + "name": "onrejected", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "reason", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult2" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is rejected." + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PromiseLike" + } + }, + "comment": { + "shortText": "Attaches callbacks for the resolution and/or rejection of the Promise." + } + }, + "@supabase/postgrest-js.PostgrestTransformBuilder.throwOnError": { + "name": "@supabase/postgrest-js.PostgrestTransformBuilder.throwOnError", + "params": [], + "comment": { + "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.\n\nhttps://github.com/supabase/supabase-js/issues/92" + } + }, + "@supabase/realtime-js.RealtimeChannel.constructor": { + "name": "@supabase/realtime-js.RealtimeChannel.constructor", + "params": [ + { + "name": "topic", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Topic name can be any string." + } + }, + { + "name": "params", + "type": { + "name": "RealtimeChannelOptions", + "type": "object", + "properties": [ + { + "name": "config", + "type": { + "type": "object", + "properties": [ + { + "name": "broadcast", + "type": { + "type": "object", + "properties": [ + { + "name": "ack", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "replay", + "type": { + "type": "nameOnly", + "name": "ReplayOption" + }, + "isOptional": true + }, + { + "name": "self", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "self option enables client to receive message it broadcast\nack option instructs server to acknowledge that broadcast message was received\nreplay option instructs server to replay broadcast messages" + } + }, + { + "name": "presence", + "type": { + "type": "object", + "properties": [ + { + "name": "enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "key", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "key option is used to track presence payload across clients" + } + }, + { + "name": "private", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "defines if the channel is private or not and if RLS policies will be used to check data" + } + } + ] + } + } + ] + } + }, + { + "name": "socket", + "type": { + "type": "nameOnly", + "name": "RealtimeClient" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + }, + "comment": { + "shortText": "Creates a channel that can broadcast messages, sync presence, and listen to Postgres changes.\n\nThe topic determines which realtime stream you are subscribing to. Config options let you\nenable acknowledgement for broadcasts, presence tracking, or private channels.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst channel = supabase.channel('room1')\nchannel\n .on('broadcast', { event: 'cursor-pos' }, (payload) => console.log(payload))\n .subscribe()\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport RealtimeClient from '@supabase/realtime-js'\n\nconst client = new RealtimeClient('https://xyzcompany.supabase.co/realtime/v1', {\n params: { apikey: 'your-publishable-key' },\n})\nconst channel = new RealtimeChannel('realtime:public:messages', { config: {} }, client)\n```" + } + ] + } + }, + "@supabase/realtime-js.RealtimeChannel.copyBindings": { + "name": "@supabase/realtime-js.RealtimeChannel.copyBindings", + "params": [ + { + "name": "other", + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + }, + "@supabase/realtime-js.RealtimeChannel.httpSend": { + "name": "@supabase/realtime-js.RealtimeChannel.httpSend", + "params": [ + { + "name": "event", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The name of the broadcast event" + } + }, + { + "name": "payload", + "type": { + "type": "intrinsic", + "name": "any" + }, + "comment": { + "shortText": "Payload to be sent (required)" + } + }, + { + "name": "opts", + "type": { + "type": "object", + "properties": [ + { + "name": "timeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + } + ] + }, + "comment": { + "shortText": "Options including timeout" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "success", + "type": { + "type": "literal", + "value": true + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "success", + "type": { + "type": "literal", + "value": false + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Sends a broadcast message explicitly via REST API.\n\nThis method always uses the REST API endpoint regardless of WebSocket connection state.\nUseful when you want to guarantee REST delivery or when gradually migrating from implicit REST fallback.\n\nPayloads that are `ArrayBuffer` or `ArrayBufferView` (e.g. `Uint8Array`) are sent as\n`application/octet-stream`; all other payloads are JSON-encoded." + } + }, + "@supabase/realtime-js.RealtimeChannel.on": { + "name": "@supabase/realtime-js.RealtimeChannel.on", + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "presence" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "sync" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + }, + "comment": { + "shortText": "Creates an event handler that listens to changes.", + "text": "- By default, Broadcast and Presence are enabled for all projects.\n- By default, listening to database changes is disabled for new projects due to database performance and security concerns. You can turn it on by managing Realtime's [replication](/docs/guides/api#realtime-api-overview).\n- You can receive the \"previous\" data for updates and deletes by setting the table's `REPLICA IDENTITY` to `FULL` (e.g., `ALTER TABLE your_table REPLICA IDENTITY FULL;`).\n- Row level security is not applied to delete statements. When RLS is enabled and replica identity is set to full, only the primary key is sent to clients.", + "examples": [ + { + "id": "listen-to-broadcast-messages", + "name": "Listen to broadcast messages", + "code": "```js\nconst channel = supabase.channel(\"room1\")\n\nchannel.on(\"broadcast\", { event: \"cursor-pos\" }, (payload) => {\n console.log(\"Cursor position received!\", payload);\n}).subscribe((status) => {\n if (status === \"SUBSCRIBED\") {\n channel.send({\n type: \"broadcast\",\n event: \"cursor-pos\",\n payload: { x: Math.random(), y: Math.random() },\n });\n }\n});\n```" + }, + { + "id": "listen-to-presence-sync", + "name": "Listen to presence sync", + "code": "```js\nconst channel = supabase.channel('room1')\nchannel\n .on('presence', { event: 'sync' }, () => {\n console.log('Synced presence state: ', channel.presenceState())\n })\n .subscribe(async (status) => {\n if (status === 'SUBSCRIBED') {\n await channel.track({ online_at: new Date().toISOString() })\n }\n })\n```" + }, + { + "id": "listen-to-presence-join", + "name": "Listen to presence join", + "code": "```js\nconst channel = supabase.channel('room1')\nchannel\n .on('presence', { event: 'join' }, ({ newPresences }) => {\n console.log('Newly joined presences: ', newPresences)\n })\n .subscribe(async (status) => {\n if (status === 'SUBSCRIBED') {\n await channel.track({ online_at: new Date().toISOString() })\n }\n })\n```" + }, + { + "id": "listen-to-presence-leave", + "name": "Listen to presence leave", + "code": "```js\nconst channel = supabase.channel('room1')\nchannel\n .on('presence', { event: 'leave' }, ({ leftPresences }) => {\n console.log('Newly left presences: ', leftPresences)\n })\n .subscribe(async (status) => {\n if (status === 'SUBSCRIBED') {\n await channel.track({ online_at: new Date().toISOString() })\n await channel.untrack()\n }\n })\n```" + }, + { + "id": "listen-to-all-database-changes", + "name": "Listen to all database changes", + "code": "```js\nsupabase\n .channel('room1')\n .on('postgres_changes', { event: '*', schema: '*' }, payload => {\n console.log('Change received!', payload)\n })\n .subscribe()\n```" + }, + { + "id": "listen-to-a-specific-table", + "name": "Listen to a specific table", + "code": "```js\nsupabase\n .channel('room1')\n .on('postgres_changes', { event: '*', schema: 'public', table: 'countries' }, payload => {\n console.log('Change received!', payload)\n })\n .subscribe()\n```" + }, + { + "id": "listen-to-inserts", + "name": "Listen to inserts", + "code": "```js\nsupabase\n .channel('room1')\n .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'countries' }, payload => {\n console.log('Change received!', payload)\n })\n .subscribe()\n```" + }, + { + "id": "listen-to-updates", + "name": "Listen to updates", + "code": "```js\nsupabase\n .channel('room1')\n .on('postgres_changes', { event: 'UPDATE', schema: 'public', table: 'countries' }, payload => {\n console.log('Change received!', payload)\n })\n .subscribe()\n```", + "description": "By default, Supabase will send only the updated record. If you want to receive the previous values as well you can\nenable full replication for the table you are listening to:\n\n```sql\nalter table \"your_table\" replica identity full;\n```" + }, + { + "id": "listen-to-deletes", + "name": "Listen to deletes", + "code": "```js\nsupabase\n .channel('room1')\n .on('postgres_changes', { event: 'DELETE', schema: 'public', table: 'countries' }, payload => {\n console.log('Change received!', payload)\n })\n .subscribe()\n```", + "description": "By default, Supabase does not send deleted records. If you want to receive the deleted record you can\nenable full replication for the table you are listening to:\n\n```sql\nalter table \"your_table\" replica identity full;\n```" + }, + { + "id": "listen-to-multiple-events", + "name": "Listen to multiple events", + "code": "```js\nsupabase\n .channel('room1')\n .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'countries' }, handleRecordInserted)\n .on('postgres_changes', { event: 'DELETE', schema: 'public', table: 'countries' }, handleRecordDeleted)\n .subscribe()\n```", + "description": "You can chain listeners if you want to listen to multiple events for each table." + }, + { + "id": "listen-to-row-level-changes", + "name": "Listen to row level changes", + "code": "```js\nsupabase\n .channel('room1')\n .on('postgres_changes', { event: 'UPDATE', schema: 'public', table: 'countries', filter: 'id=eq.200' }, handleRecordUpdated)\n .subscribe()\n```", + "description": "You can listen to individual rows using the format `{table}:{col}=eq.{val}` - where `{col}` is the column name, and `{val}` is the value which you want to match." + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "presence" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "join" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "name": "RealtimePresenceJoinPayload", + "type": "object", + "properties": [ + { + "name": "currentPresences", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + }, + { + "name": "event" + }, + { + "name": "key", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "newPresences", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "presence" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "leave" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "name": "RealtimePresenceLeavePayload", + "type": "object", + "properties": [ + { + "name": "currentPresences", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + }, + { + "name": "event" + }, + { + "name": "key", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "leftPresences", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "presence" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "*" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "union", + "subTypes": [ + { + "name": "RealtimePresenceJoinPayload", + "type": "object", + "properties": [ + { + "name": "currentPresences", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + }, + { + "name": "event" + }, + { + "name": "key", + "type": "[Circular]" + }, + { + "name": "newPresences", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + } + ] + }, + { + "name": "RealtimePresenceLeavePayload", + "type": "object", + "properties": [ + { + "name": "currentPresences", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + }, + { + "name": "event" + }, + { + "name": "key", + "type": "[Circular]" + }, + { + "name": "leftPresences", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + } + ] + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "postgres_changes" + } + }, + { + "name": "filter", + "type": { + "name": "RealtimePostgresChangesFilter", + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "*" + }, + "comment": { + "shortText": "The type of database change to listen to." + } + }, + { + "name": "filter", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Receive database changes when filter is matched." + } + }, + { + "name": "schema", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The database schema to listen to." + } + }, + { + "name": "table", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The database table to listen to." + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "union", + "name": "RealtimePostgresChangesPayload", + "subTypes": [ + { + "type": "nameOnly", + "name": "RealtimePostgresInsertPayload" + }, + { + "type": "nameOnly", + "name": "RealtimePostgresUpdatePayload" + }, + { + "type": "nameOnly", + "name": "RealtimePostgresDeletePayload" + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "postgres_changes" + } + }, + { + "name": "filter", + "type": { + "name": "RealtimePostgresChangesFilter", + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "INSERT" + }, + "comment": { + "shortText": "The type of database change to listen to." + } + }, + { + "name": "filter", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Receive database changes when filter is matched." + } + }, + { + "name": "schema", + "type": "[Circular]", + "comment": { + "shortText": "The database schema to listen to." + } + }, + { + "name": "table", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The database table to listen to." + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "nameOnly", + "name": "RealtimePostgresInsertPayload" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "postgres_changes" + } + }, + { + "name": "filter", + "type": { + "name": "RealtimePostgresChangesFilter", + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "UPDATE" + }, + "comment": { + "shortText": "The type of database change to listen to." + } + }, + { + "name": "filter", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Receive database changes when filter is matched." + } + }, + { + "name": "schema", + "type": "[Circular]", + "comment": { + "shortText": "The database schema to listen to." + } + }, + { + "name": "table", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The database table to listen to." + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "nameOnly", + "name": "RealtimePostgresUpdatePayload" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "postgres_changes" + } + }, + { + "name": "filter", + "type": { + "name": "RealtimePostgresChangesFilter", + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "DELETE" + }, + "comment": { + "shortText": "The type of database change to listen to." + } + }, + { + "name": "filter", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Receive database changes when filter is matched." + } + }, + { + "name": "schema", + "type": "[Circular]", + "comment": { + "shortText": "The database schema to listen to." + } + }, + { + "name": "table", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The database table to listen to." + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "nameOnly", + "name": "RealtimePostgresDeletePayload" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "postgres_changes" + } + }, + { + "name": "filter", + "type": { + "name": "RealtimePostgresChangesFilter", + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "INSERT" + }, + { + "type": "literal", + "value": "UPDATE" + }, + { + "type": "literal", + "value": "DELETE" + }, + { + "type": "literal", + "value": "*" + } + ] + }, + "comment": { + "shortText": "The type of database change to listen to." + } + }, + { + "name": "filter", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Receive database changes when filter is matched." + } + }, + { + "name": "schema", + "type": "[Circular]", + "comment": { + "shortText": "The database schema to listen to." + } + }, + { + "name": "table", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The database table to listen to." + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "union", + "name": "RealtimePostgresChangesPayload", + "subTypes": [ + { + "type": "nameOnly", + "name": "RealtimePostgresInsertPayload" + }, + { + "type": "nameOnly", + "name": "RealtimePostgresUpdatePayload" + }, + { + "type": "nameOnly", + "name": "RealtimePostgresDeletePayload" + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + }, + "comment": { + "shortText": "One of \"broadcast\", \"presence\", or \"postgres_changes\"." + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "comment": { + "shortText": "Custom object specific to the Realtime feature detailing which payloads to receive." + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "meta", + "type": { + "type": "object", + "properties": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "replayed", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + } + ] + }, + "isOptional": true + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "Function to be invoked when event handler is triggered." + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "meta", + "type": { + "type": "object", + "properties": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "replayed", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + } + ] + }, + "isOptional": true + }, + { + "name": "payload", + "type": { + "type": "nameOnly", + "name": "T" + } + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "*", + "name": "ALL" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": "[Circular]" + }, + { + "name": "payload", + "type": { + "type": "nameOnly", + "name": "RealtimeBroadcastPayload" + } + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "INSERT", + "name": "INSERT" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": "[Circular]" + }, + { + "name": "payload", + "type": { + "type": "nameOnly", + "name": "RealtimeBroadcastInsertPayload" + } + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "UPDATE", + "name": "UPDATE" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": "[Circular]" + }, + { + "name": "payload", + "type": { + "type": "nameOnly", + "name": "RealtimeBroadcastUpdatePayload" + } + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "DELETE", + "name": "DELETE" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": "[Circular]" + }, + { + "name": "payload", + "type": { + "type": "nameOnly", + "name": "RealtimeBroadcastDeletePayload" + } + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "system" + } + }, + { + "name": "filter" + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + } + ] + }, + "@supabase/realtime-js.RealtimeChannel.presenceState": { + "name": "@supabase/realtime-js.RealtimeChannel.presenceState", + "params": [], + "ret": { + "type": { + "name": "RealtimePresenceState", + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + } + }, + "comment": { + "shortText": "Returns the current presence state for this channel.\n\nThe shape is a map keyed by presence key (for example a user id) where each entry contains the\ntracked metadata for that user." + } + }, + "@supabase/realtime-js.RealtimeChannel.send": { + "name": "@supabase/realtime-js.RealtimeChannel.send", + "params": [ + { + "name": "args", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The name of the event being sent" + } + }, + { + "name": "payload", + "type": { + "type": "intrinsic", + "name": "any" + }, + "isOptional": true, + "comment": { + "shortText": "Payload to be sent" + } + }, + { + "name": "type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "broadcast" + }, + { + "type": "literal", + "value": "presence" + }, + { + "type": "literal", + "value": "postgres_changes" + } + ] + }, + "comment": { + "shortText": "The type of event to send" + } + } + ] + }, + "comment": { + "shortText": "Arguments to send to channel" + } + }, + { + "name": "opts", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + "comment": { + "shortText": "Options to be used during the send process" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "RealtimeChannelSendResponse", + "subTypes": [ + { + "type": "literal", + "value": "ok" + }, + { + "type": "literal", + "value": "timed out" + }, + { + "type": "literal", + "value": "error" + }, + null + ] + } + } + }, + "comment": { + "shortText": "Sends a message into the channel.", + "text": "- When using REST you don't need to subscribe to the channel\n- REST calls are only available from 2.37.0 onwards\n- If you create a channel only to send a REST broadcast, remove it from\n the client when the send completes", + "examples": [ + { + "id": "send-a-message-via-websocket", + "name": "Send a message via websocket", + "code": "```js\nconst channel = supabase.channel('room1')\n\nchannel.subscribe((status) => {\n if (status === 'SUBSCRIBED') {\n channel.send({\n type: 'broadcast',\n event: 'cursor-pos',\n payload: { x: Math.random(), y: Math.random() },\n })\n }\n})\n```", + "response": "```js\nok | timed out | error\n```" + }, + { + "id": "send-a-message-via-rest", + "name": "Send a message via REST", + "code": "```js\nconst channel = supabase.channel('room1')\n\ntry {\n await channel.httpSend('cursor-pos', { x: Math.random(), y: Math.random() })\n} finally {\n await supabase.removeChannel(channel)\n}\n```" + } + ] + } + }, + "@supabase/realtime-js.RealtimeChannel.subscribe": { + "name": "@supabase/realtime-js.RealtimeChannel.subscribe", + "params": [ + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "status", + "type": { + "type": "nameOnly", + "name": "REALTIME_SUBSCRIBE_STATES" + } + }, + { + "name": "err", + "type": { + "type": "nameOnly", + "name": "Error" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + }, + "isOptional": true + }, + { + "name": "timeout", + "type": { + "type": "intrinsic", + "name": "number" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + }, + "comment": { + "shortText": "Subscribe registers your client with the server.\n\nThe optional `callback` receives a `status` and, on failure, an `err` argument.\nLog the full `err` so its `cause`, `name`, and any structured fields aren't hidden\nbehind `err.message`.", + "examples": [ + { + "id": "handling-errors", + "name": "Handling errors", + "code": "```js\nsupabase.channel('room1').subscribe((status, err) => {\n if (status === 'CHANNEL_ERROR' || status === 'TIMED_OUT') {\n // Log the full error: its `cause` often holds the underlying reason.\n console.error(status, err)\n }\n})\n```" + } + ] + } + }, + "@supabase/realtime-js.RealtimeChannel.teardown": { + "name": "@supabase/realtime-js.RealtimeChannel.teardown", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Destroys and stops related timers." + } + }, + "@supabase/realtime-js.RealtimeChannel.track": { + "name": "@supabase/realtime-js.RealtimeChannel.track", + "params": [ + { + "name": "payload", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + } + }, + { + "name": "opts", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "RealtimeChannelSendResponse", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + } + }, + "comment": { + "shortText": "Sends the supplied payload to the presence tracker so other subscribers can see that this\nclient is online. Use `untrack` to stop broadcasting presence for the same key." + } + }, + "@supabase/realtime-js.RealtimeChannel.unsubscribe": { + "name": "@supabase/realtime-js.RealtimeChannel.unsubscribe", + "params": [ + { + "name": "timeout", + "type": { + "type": "intrinsic", + "name": "number" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "RealtimeChannelSendResponse", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + } + }, + "comment": { + "shortText": "Leaves the channel.\n\nUnsubscribes from server events, and instructs channel to terminate on server.\nTriggers onClose() hooks.\n\nTo receive leave acknowledgements, use the a `receive` hook to bind to the server ack, ie:\nchannel.unsubscribe().receive(\"ok\", () => alert(\"left!\") )" + } + }, + "@supabase/realtime-js.RealtimeChannel.untrack": { + "name": "@supabase/realtime-js.RealtimeChannel.untrack", + "params": [ + { + "name": "opts", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "RealtimeChannelSendResponse", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + } + }, + "comment": { + "shortText": "Removes the current presence state for this client." + } + }, + "@supabase/realtime-js.RealtimeChannel.updateJoinPayload": { + "name": "@supabase/realtime-js.RealtimeChannel.updateJoinPayload", + "params": [ + { + "name": "payload", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Updates the payload that will be sent the next time the channel joins (reconnects).\nUseful for rotating access tokens or updating config without re-creating the channel." + } + }, + "@supabase/realtime-js.RealtimeClient.constructor": { + "name": "@supabase/realtime-js.RealtimeClient.constructor", + "params": [ + { + "name": "endPoint", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The string WebSocket endpoint, ie, \"ws://example.com/socket\", \"wss://example.com\", \"/socket\" (inherited host & protocol)" + } + }, + { + "name": "options", + "type": { + "name": "RealtimeClientOptions", + "type": "object", + "properties": [ + { + "name": "accessToken", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "literal", + "value": null + } + ] + } + } + } + }, + "isOptional": true + }, + { + "name": "decode", + "type": { + "type": "nameOnly", + "name": "Decode" + }, + "isOptional": true + }, + { + "name": "disconnectOnEmptyChannelsAfterMs", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "encode", + "type": { + "type": "nameOnly", + "name": "Encode" + }, + "isOptional": true + }, + { + "name": "fetch", + "type": { + "type": "nameOnly", + "name": "Fetch" + }, + "isOptional": true + }, + { + "name": "headers", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true + }, + { + "name": "heartbeatCallback", + "type": { + "type": "function", + "params": [ + { + "name": "status", + "type": { + "type": "nameOnly", + "name": "HeartbeatStatus" + } + }, + { + "name": "latency", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + }, + "isOptional": true + }, + { + "name": "heartbeatIntervalMs", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "log_level", + "type": { + "type": "nameOnly", + "name": "LogLevel" + }, + "isOptional": true + }, + { + "name": "logger", + "type": { + "type": "function", + "params": [ + { + "name": "kind", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "msg", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "any" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + }, + "isOptional": true + }, + { + "name": "logLevel", + "type": { + "type": "nameOnly", + "name": "LogLevel" + }, + "isOptional": true + }, + { + "name": "params", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + "isOptional": true + }, + { + "name": "reconnectAfterMs", + "type": { + "type": "function", + "params": [ + { + "name": "tries", + "type": { + "type": "intrinsic", + "name": "number" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "number" + } + } + }, + "isOptional": true + }, + { + "name": "sessionStorage", + "type": { + "type": "nameOnly", + "name": "Storage" + }, + "isOptional": true, + "comment": { + "shortText": "Storage compatible object used by the underlying socket for longpoll fallback history.\nProvide a custom implementation in environments where reading `globalThis.sessionStorage`\nthrows (sandboxed iframes, in-app webviews, \"block third-party storage\" privacy modes).\nDefaults to `globalThis.sessionStorage` when accessible, otherwise an in-memory store." + } + }, + { + "name": "timeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "transport", + "type": { + "type": "object", + "name": "WebSocketLikeConstructor", + "properties": [] + }, + "isOptional": true + }, + { + "name": "vsn", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "worker", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "workerUrl", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeClient" + } + }, + "comment": { + "shortText": "Initializes the Socket.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst channel = supabase.channel('room1')\nchannel\n .on('broadcast', { event: 'cursor-pos' }, (payload) => console.log(payload))\n .subscribe()\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport RealtimeClient from '@supabase/realtime-js'\n\nconst client = new RealtimeClient('https://xyzcompany.supabase.co/realtime/v1', {\n params: { apikey: 'your-publishable-key' },\n})\nclient.connect()\n```" + } + ] + } + }, + "@supabase/realtime-js.RealtimeClient.channel": { + "name": "@supabase/realtime-js.RealtimeClient.channel", + "params": [ + { + "name": "topic", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "params", + "type": { + "name": "RealtimeChannelOptions", + "type": "object", + "properties": [ + { + "name": "config", + "type": { + "type": "object", + "properties": [ + { + "name": "broadcast", + "type": { + "type": "object", + "properties": [ + { + "name": "ack", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "replay", + "type": { + "type": "nameOnly", + "name": "ReplayOption" + }, + "isOptional": true + }, + { + "name": "self", + "type": "[Circular]", + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "self option enables client to receive message it broadcast\nack option instructs server to acknowledge that broadcast message was received\nreplay option instructs server to replay broadcast messages" + } + }, + { + "name": "presence", + "type": { + "type": "object", + "properties": [ + { + "name": "enabled", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "key", + "type": "[Circular]", + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "key option is used to track presence payload across clients" + } + }, + { + "name": "private", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "defines if the channel is private or not and if RLS policies will be used to check data" + } + } + ] + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + }, + "comment": { + "shortText": "Creates (or reuses) a RealtimeChannel for the provided topic.\n\nTopics are automatically prefixed with `realtime:` to match the Realtime service.\nIf a channel with the same topic already exists it will be returned instead of creating\na duplicate connection." + } + }, + "@supabase/realtime-js.RealtimeClient.connect": { + "name": "@supabase/realtime-js.RealtimeClient.connect", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Connects the socket, unless already connected." + } + }, + "@supabase/realtime-js.RealtimeClient.connectionState": { + "name": "@supabase/realtime-js.RealtimeClient.connectionState", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "ConnectionState" + } + }, + "comment": { + "shortText": "Returns the current state of the socket." + } + }, + "@supabase/realtime-js.RealtimeClient.disconnect": { + "name": "@supabase/realtime-js.RealtimeClient.disconnect", + "params": [ + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "A numeric status code to send on disconnect." + } + }, + { + "name": "reason", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "A custom reason for the disconnect." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "ok" + }, + { + "type": "literal", + "value": "timeout" + } + ] + } + } + }, + "comment": { + "shortText": "Disconnects the socket." + } + }, + "@supabase/realtime-js.RealtimeClient.endpointURL": { + "name": "@supabase/realtime-js.RealtimeClient.endpointURL", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "string" + } + }, + "comment": { + "shortText": "Returns the URL of the websocket." + } + }, + "@supabase/realtime-js.RealtimeClient.getChannels": { + "name": "@supabase/realtime-js.RealtimeClient.getChannels", + "params": [], + "ret": { + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + "comment": { + "shortText": "Returns all created channels" + } + }, + "@supabase/realtime-js.RealtimeClient.isConnected": { + "name": "@supabase/realtime-js.RealtimeClient.isConnected", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "boolean" + } + }, + "comment": { + "shortText": "Returns `true` is the connection is open." + } + }, + "@supabase/realtime-js.RealtimeClient.isConnecting": { + "name": "@supabase/realtime-js.RealtimeClient.isConnecting", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "boolean" + } + }, + "comment": { + "shortText": "Returns `true` if the connection is currently connecting." + } + }, + "@supabase/realtime-js.RealtimeClient.isDisconnecting": { + "name": "@supabase/realtime-js.RealtimeClient.isDisconnecting", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "boolean" + } + }, + "comment": { + "shortText": "Returns `true` if the connection is currently disconnecting." + } + }, + "@supabase/realtime-js.RealtimeClient.log": { + "name": "@supabase/realtime-js.RealtimeClient.log", + "params": [ + { + "name": "kind", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "msg", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "any" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Logs the message.\n\nFor customized logging, `this.logger` can be overridden in Client constructor." + } + }, + "@supabase/realtime-js.RealtimeClient.onHeartbeat": { + "name": "@supabase/realtime-js.RealtimeClient.onHeartbeat", + "params": [ + { + "name": "callback", + "type": { + "type": "nameOnly", + "name": "HeartbeatCallback" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Sets a callback that receives lifecycle events for internal heartbeat messages.\nUseful for instrumenting connection health (e.g. sent/ok/timeout/disconnected)." + } + }, + "@supabase/realtime-js.RealtimeClient.push": { + "name": "@supabase/realtime-js.RealtimeClient.push", + "params": [ + { + "name": "data", + "type": { + "name": "RealtimeMessage", + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "join_ref", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "payload", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "ref", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "topic", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Push out a message if the socket is connected.\n\nIf the socket is not connected, the message gets enqueued within a local buffer, and sent out when a connection is next established." + } + }, + "@supabase/realtime-js.RealtimeClient.removeAllChannels": { + "name": "@supabase/realtime-js.RealtimeClient.removeAllChannels", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "array", + "elemType": { + "type": "union", + "name": "RealtimeRemoveChannelResponse", + "subTypes": [ + { + "type": "literal", + "value": "ok" + }, + { + "type": "literal", + "value": "timed out" + }, + { + "type": "literal", + "value": "error" + }, + null + ] + } + } + } + }, + "comment": { + "shortText": "Unsubscribes, removes and tears down all channels" + } + }, + "@supabase/realtime-js.RealtimeClient.removeChannel": { + "name": "@supabase/realtime-js.RealtimeClient.removeChannel", + "params": [ + { + "name": "channel", + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + }, + "comment": { + "shortText": "A RealtimeChannel instance" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "RealtimeRemoveChannelResponse", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + } + }, + "comment": { + "shortText": "Unsubscribes, removes and tears down a single channel" + } + }, + "@supabase/realtime-js.RealtimeClient.sendHeartbeat": { + "name": "@supabase/realtime-js.RealtimeClient.sendHeartbeat", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "Sends a heartbeat message if the socket is connected." + } + }, + "@supabase/realtime-js.RealtimeClient.setAuth": { + "name": "@supabase/realtime-js.RealtimeClient.setAuth", + "params": [ + { + "name": "token", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "comment": { + "shortText": "A JWT string to override the token set on the client." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "Sets the JWT access token used for channel subscription authorization and Realtime RLS.\n\nIf param is null it will use the `accessToken` callback function or the token set on the client.\n\nOn callback used, it will set the value of the token internal to the client.\n\nWhen a token is explicitly provided, it will be preserved across channel operations\n(including removeChannel and resubscribe). The `accessToken` callback will not be\ninvoked until `setAuth()` is called without arguments.", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\nSetting the authorization header\n// Use a manual token (preserved across resubscribes, ignores accessToken callback)\nclient.realtime.setAuth('my-custom-jwt')\n\n// Switch back to using the accessToken callback\nclient.realtime.setAuth()\n```" + } + ] + } + }, + "@supabase/realtime-js.RealtimePresence.constructor": { + "name": "@supabase/realtime-js.RealtimePresence.constructor", + "params": [ + { + "name": "channel", + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + }, + "comment": { + "shortText": "The realtime channel to bind to." + } + }, + { + "name": "opts", + "type": { + "type": "nameOnly", + "name": "RealtimePresenceOptions" + }, + "isOptional": true, + "comment": { + "shortText": "Optional custom event names, e.g. `{ events: { state: 'state', diff: 'diff' } }`." + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimePresence" + } + }, + "comment": { + "shortText": "Creates a Presence helper that keeps the local presence state in sync with the server.", + "examples": [ + { + "id": "example-for-a-presence-channel", + "name": "Example for a presence channel", + "code": "```ts\nconst presence = new RealtimePresence(channel)\n\nchannel.on('presence', ({ event, key }) => {\n console.log(`Presence ${event} on ${key}`)\n})\n```" + } + ] + } + }, + "@supabase/realtime-js.WebSocketFactory.getWebSocketConstructor": { + "name": "@supabase/realtime-js.WebSocketFactory.getWebSocketConstructor", + "params": [], + "ret": { + "type": { + "type": "function", + "params": [ + { + "name": "url", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "protocols", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "WebSocket" + } + } + } + }, + "comment": { + "shortText": "Returns the best available WebSocket constructor for the current runtime.", + "examples": [ + { + "id": "example-with-error-handling", + "name": "Example with error handling", + "code": "```ts\ntry {\n const WS = WebSocketFactory.getWebSocketConstructor()\n const socket = new WS('wss://example.com/socket')\n} catch (error) {\n console.error('WebSocket not available in this environment.', error)\n}\n```" + } + ] + } + }, + "@supabase/realtime-js.WebSocketFactory.isWebSocketSupported": { + "name": "@supabase/realtime-js.WebSocketFactory.isWebSocketSupported", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "boolean" + } + }, + "comment": { + "shortText": "Detects whether the runtime can establish WebSocket connections.", + "examples": [ + { + "id": "example-in-a-node-js-script", + "name": "Example in a Node.js script", + "code": "```ts\nif (!WebSocketFactory.isWebSocketSupported()) {\n console.error('WebSockets are required for this script.')\n process.exitCode = 1\n}\n```" + } + ] + } + }, + "@supabase/realtime-js.WebSocketLike.addEventListener": { + "name": "@supabase/realtime-js.WebSocketLike.addEventListener", + "params": [ + { + "name": "type", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "listener", + "type": { + "type": "nameOnly", + "name": "EventListener" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Registers an event listener on the socket (compatible with browser WebSocket API)." + } + }, + "@supabase/realtime-js.WebSocketLike.close": { + "name": "@supabase/realtime-js.WebSocketLike.close", + "params": [ + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "reason", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Closes the socket, optionally providing a close code and reason." + } + }, + "@supabase/realtime-js.WebSocketLike.removeEventListener": { + "name": "@supabase/realtime-js.WebSocketLike.removeEventListener", + "params": [ + { + "name": "type", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "listener", + "type": { + "type": "nameOnly", + "name": "EventListener" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Removes a previously registered event listener." + } + }, + "@supabase/realtime-js.WebSocketLike.send": { + "name": "@supabase/realtime-js.WebSocketLike.send", + "params": [ + { + "name": "data", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "nameOnly", + "name": "ArrayBufferLike" + }, + { + "type": "nameOnly", + "name": "Blob" + }, + { + "type": "nameOnly", + "name": "ArrayBufferView" + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Sends data through the socket using the underlying implementation." + } + }, + "@supabase/realtime-js.WebSocketLikeConstructor.constructor": { + "name": "@supabase/realtime-js.WebSocketLikeConstructor.constructor", + "params": [ + { + "name": "address", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "subprotocols", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "object", + "name": "WebSocketLike", + "properties": [ + { + "name": "binaryType", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "bufferedAmount", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "CLOSED", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "CLOSING", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "CONNECTING", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "dispatchEvent", + "type": { + "type": "function", + "params": [ + { + "name": "event", + "type": { + "type": "nameOnly", + "name": "Event" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "boolean" + } + } + }, + "isOptional": true + }, + { + "name": "extensions", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "onclose", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "this", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "ev", + "type": { + "type": "nameOnly", + "name": "CloseEvent" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "any" + } + } + } + ] + } + }, + { + "name": "onerror", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "this", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "ev", + "type": { + "type": "nameOnly", + "name": "Event" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "any" + } + } + } + ] + } + }, + { + "name": "onmessage", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "this", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "ev", + "type": { + "type": "nameOnly", + "name": "MessageEvent" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "any" + } + } + } + ] + } + }, + { + "name": "onopen", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "this", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "ev", + "type": { + "type": "nameOnly", + "name": "Event" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "any" + } + } + } + ] + } + }, + { + "name": "OPEN", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "protocol", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "readyState", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + }, + "@supabase/storage-js.StorageApiError.constructor": { + "name": "@supabase/storage-js.StorageApiError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "statusCode", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "namespace", + "type": { + "type": "union", + "name": "ErrorNamespace", + "subTypes": [ + { + "type": "literal", + "value": "storage" + }, + { + "type": "literal", + "value": "vectors" + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "StorageApiError" + } + } + }, + "@supabase/storage-js.StorageApiError.toJSON": { + "name": "@supabase/storage-js.StorageApiError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + }, + { + "name": "statusCode", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ] + } + } + }, + "@supabase/storage-js.StorageClient.constructor": { + "name": "@supabase/storage-js.StorageClient.constructor", + "params": [ + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "headers", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + } + }, + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RequestInfo" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true + }, + { + "name": "opts", + "type": { + "type": "object", + "name": "StorageClientOptions", + "properties": [ + { + "name": "useNewHostname", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "StorageClient" + } + }, + "comment": { + "shortText": "Creates a client for Storage buckets, files, analytics, and vectors.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst avatars = supabase.storage.from('avatars')\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport { StorageClient } from '@supabase/storage-js'\n\nconst storage = new StorageClient('https://xyzcompany.supabase.co/storage/v1', {\n apikey: 'your-publishable-key',\n})\nconst avatars = storage.from('avatars')\n```" + } + ] + } + }, + "@supabase/storage-js.StorageClient.createBucket": { + "name": "@supabase/storage-js.StorageClient.createBucket", + "params": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "A unique identifier for the bucket you are creating." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "allowedMimeTypes", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "specifies the allowed mime types that this bucket can accept during upload.\nThe default value is null, which allows files with all mime types to be uploaded.\nEach mime type specified can be a wildcard, e.g. image/*, or a specific mime type, e.g. image/png." + } + }, + { + "name": "fileSizeLimit", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "specifies the max file size in bytes that can be uploaded to this bucket.\nThe global file size limit takes precedence over this value.\nThe default value is null, which doesn't set a per bucket file size limit." + } + }, + { + "name": "public", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "comment": { + "shortText": "The visibility of the bucket. Public buckets don't require an authorization token to download objects, but still require a valid token for all other operations. By default, buckets are private." + } + }, + { + "name": "type", + "type": { + "type": "union", + "name": "BucketType", + "subTypes": [ + { + "type": "literal", + "value": "STANDARD" + }, + { + "type": "literal", + "value": "ANALYTICS" + }, + null + ] + }, + "isOptional": true, + "comment": { + "shortText": "(private-beta) specifies the bucket type. see `BucketType` for more details.\n - default bucket type is `STANDARD`" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a new Storage bucket", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: `insert`\n - `objects` table permissions: none\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "create-bucket", + "name": "Create bucket", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .createBucket('avatars', {\n public: false,\n allowedMimeTypes: ['image/png'],\n fileSizeLimit: 1024\n })\n```", + "response": "```json\n{\n \"data\": {\n \"name\": \"avatars\"\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.StorageClient.deleteBucket": { + "name": "@supabase/storage-js.StorageClient.deleteBucket", + "params": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The unique identifier of the bucket you would like to delete." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Deletes an existing bucket. A bucket can't be deleted with existing objects inside it.\nYou must first `empty()` the bucket.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: `select` and `delete`\n - `objects` table permissions: none\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "delete-bucket", + "name": "Delete bucket", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .deleteBucket('avatars')\n```", + "response": "```json\n{\n \"data\": {\n \"message\": \"Successfully deleted\"\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.StorageClient.emptyBucket": { + "name": "@supabase/storage-js.StorageClient.emptyBucket", + "params": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The unique identifier of the bucket you would like to empty." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Removes all objects inside a single bucket.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: `select`\n - `objects` table permissions: `select` and `delete`\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "empty-bucket", + "name": "Empty bucket", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .emptyBucket('avatars')\n```", + "response": "```json\n{\n \"data\": {\n \"message\": \"Successfully emptied\"\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.StorageClient.from": { + "name": "@supabase/storage-js.StorageClient.from", + "params": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The bucket id to operate on." + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "default" + } + }, + "comment": { + "shortText": "Perform file operation in a bucket.", + "examples": [ + { + "id": "accessing-a-bucket", + "name": "Accessing a bucket", + "code": "```typescript\nconst avatars = supabase.storage.from('avatars')\n```" + } + ] + } + }, + "@supabase/storage-js.StorageClient.getBucket": { + "name": "@supabase/storage-js.StorageClient.getBucket", + "params": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The unique identifier of the bucket you would like to retrieve." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "name": "Bucket", + "properties": [ + { + "name": "allowed_mime_types", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true + }, + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "file_size_limit", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "owner", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "public", + "type": { + "type": "intrinsic", + "name": "boolean" + } + }, + { + "name": "type", + "type": { + "type": "union", + "name": "BucketType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + }, + "isOptional": true + }, + { + "name": "updated_at", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Retrieves the details of an existing Storage bucket.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: `select`\n - `objects` table permissions: none\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "get-bucket", + "name": "Get bucket", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .getBucket('avatars')\n```", + "response": "```json\n{\n \"data\": {\n \"id\": \"avatars\",\n \"name\": \"avatars\",\n \"owner\": \"\",\n \"public\": false,\n \"file_size_limit\": 1024,\n \"allowed_mime_types\": [\n \"image/png\"\n ],\n \"created_at\": \"2024-05-22T22:26:05.100Z\",\n \"updated_at\": \"2024-05-22T22:26:05.100Z\"\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.StorageClient.listBuckets": { + "name": "@supabase/storage-js.StorageClient.listBuckets", + "params": [ + { + "name": "options", + "type": { + "type": "object", + "name": "ListBucketOptions", + "properties": [ + { + "name": "limit", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "offset", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "search", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "sortColumn", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "id" + }, + { + "type": "literal", + "value": "name" + }, + { + "type": "literal", + "value": "created_at" + }, + { + "type": "literal", + "value": "updated_at" + } + ] + }, + "isOptional": true + }, + { + "name": "sortOrder", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "asc" + }, + { + "type": "literal", + "value": "desc" + } + ] + }, + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Query parameters for listing buckets" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "Bucket", + "properties": [ + { + "name": "allowed_mime_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "file_size_limit", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "name", + "type": "[Circular]" + }, + { + "name": "owner", + "type": "[Circular]" + }, + { + "name": "public", + "type": "[Circular]" + }, + { + "name": "type", + "type": { + "type": "union", + "name": "BucketType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + }, + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Retrieves the details of all Storage buckets within an existing project.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: `select`\n - `objects` table permissions: none\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "list-buckets", + "name": "List buckets", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .listBuckets()\n```" + }, + { + "id": "list-buckets-with-options", + "name": "List buckets with options", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .listBuckets({\n limit: 10,\n offset: 0,\n sortColumn: 'created_at',\n sortOrder: 'desc',\n search: 'prod'\n })\n```" + } + ] + } + }, + "@supabase/storage-js.StorageClient.setHeader": { + "name": "@supabase/storage-js.StorageClient.setHeader", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Header name" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Header value" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set an HTTP header for the request.\nCreates a shallow copy of headers to avoid mutating shared state." + } + }, + "@supabase/storage-js.StorageClient.throwOnError": { + "name": "@supabase/storage-js.StorageClient.throwOnError", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Enable throwing errors instead of returning them.\nWhen enabled, errors are thrown instead of returned in { data, error } format." + } + }, + "@supabase/storage-js.StorageClient.updateBucket": { + "name": "@supabase/storage-js.StorageClient.updateBucket", + "params": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "A unique identifier for the bucket you are updating." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "allowedMimeTypes", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "specifies the allowed mime types that this bucket can accept during upload.\nThe default value is null, which allows files with all mime types to be uploaded.\nEach mime type specified can be a wildcard, e.g. image/*, or a specific mime type, e.g. image/png." + } + }, + { + "name": "fileSizeLimit", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "specifies the max file size in bytes that can be uploaded to this bucket.\nThe global file size limit takes precedence over this value.\nThe default value is null, which doesn't set a per bucket file size limit." + } + }, + { + "name": "public", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "comment": { + "shortText": "The visibility of the bucket. Public buckets don't require an authorization token to download objects, but still require a valid token for all other operations." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Updates a Storage bucket", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: `select` and `update`\n - `objects` table permissions: none\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "update-bucket", + "name": "Update bucket", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .updateBucket('avatars', {\n public: false,\n allowedMimeTypes: ['image/png'],\n fileSizeLimit: 1024\n })\n```", + "response": "```json\n{\n \"data\": {\n \"message\": \"Successfully updated\"\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.StorageError.constructor": { + "name": "@supabase/storage-js.StorageError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "namespace", + "type": { + "type": "union", + "name": "ErrorNamespace", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "statusCode", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + }, + "@supabase/storage-js.StorageError.toJSON": { + "name": "@supabase/storage-js.StorageError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + }, + { + "name": "statusCode", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ] + } + } + }, + "@supabase/storage-js.StorageUnknownError.constructor": { + "name": "@supabase/storage-js.StorageUnknownError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "originalError", + "type": { + "type": "intrinsic", + "name": "unknown" + } + }, + { + "name": "namespace", + "type": { + "type": "union", + "name": "ErrorNamespace", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "StorageUnknownError" + } + } + }, + "@supabase/storage-js.StorageUnknownError.toJSON": { + "name": "@supabase/storage-js.StorageUnknownError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + }, + { + "name": "statusCode", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ] + } + } + }, + "@supabase/storage-js.StorageVectorsApiError.constructor": { + "name": "@supabase/storage-js.StorageVectorsApiError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "statusCode", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "StorageVectorsApiError" + } + } + }, + "@supabase/storage-js.StorageVectorsApiError.toJSON": { + "name": "@supabase/storage-js.StorageVectorsApiError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + }, + { + "name": "statusCode", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ] + } + } + }, + "@supabase/storage-js.StorageVectorsError.constructor": { + "name": "@supabase/storage-js.StorageVectorsError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "StorageVectorsError" + } + } + }, + "@supabase/storage-js.StorageVectorsError.toJSON": { + "name": "@supabase/storage-js.StorageVectorsError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + }, + { + "name": "statusCode", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ] + } + } + }, + "@supabase/storage-js.StorageVectorsUnknownError.constructor": { + "name": "@supabase/storage-js.StorageVectorsUnknownError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "originalError", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "StorageVectorsUnknownError" + } + } + }, + "@supabase/storage-js.StorageVectorsUnknownError.toJSON": { + "name": "@supabase/storage-js.StorageVectorsUnknownError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + }, + { + "name": "statusCode", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ] + } + } + }, + "@supabase/storage-js.isStorageError": { + "name": "@supabase/storage-js.isStorageError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "unknown" + }, + "comment": { + "shortText": "The error to check" + } + } + ], + "comment": { + "shortText": "Type guard to check if an error is a StorageError" + } + }, + "@supabase/storage-js.isStorageVectorsError": { + "name": "@supabase/storage-js.isStorageVectorsError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "unknown" + }, + "comment": { + "shortText": "The error to check" + } + } + ], + "comment": { + "shortText": "Type guard to check if an error is a StorageVectorsError" + } + }, + "@supabase/storage-js.packages/BlobDownloadBuilder.default.constructor": { + "name": "@supabase/storage-js.packages/BlobDownloadBuilder.default.constructor", + "params": [ + { + "name": "downloadFn", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + } + } + }, + { + "name": "shouldThrowOnError", + "type": { + "type": "intrinsic", + "name": "boolean" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "default" + } + } + }, + "@supabase/storage-js.packages/BlobDownloadBuilder.default.asStream": { + "name": "@supabase/storage-js.packages/BlobDownloadBuilder.default.asStream", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "default" + } + } + }, + "@supabase/storage-js.packages/BlobDownloadBuilder.default.catch": { + "name": "@supabase/storage-js.packages/BlobDownloadBuilder.default.catch", + "params": [ + { + "name": "onrejected", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "reason", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is rejected." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "union", + "name": "DownloadResult", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "nameOnly", + "name": "Blob" + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + }, + { + "type": "nameOnly", + "name": "TResult" + } + ] + } + } + }, + "comment": { + "shortText": "Attaches a callback for only the rejection of the Promise." + } + }, + "@supabase/storage-js.packages/BlobDownloadBuilder.default.finally": { + "name": "@supabase/storage-js.packages/BlobDownloadBuilder.default.finally", + "params": [ + { + "name": "onfinally", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is settled (fulfilled or rejected)." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "DownloadResult", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "nameOnly", + "name": "Blob" + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The\nresolved value cannot be modified from the callback." + } + }, + "@supabase/storage-js.packages/BlobDownloadBuilder.default.then": { + "name": "@supabase/storage-js.packages/BlobDownloadBuilder.default.then", + "params": [ + { + "name": "onfulfilled", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "value", + "type": { + "type": "union", + "name": "DownloadResult", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "nameOnly", + "name": "Blob" + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult1" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is resolved." + } + }, + { + "name": "onrejected", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "reason", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult2" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is rejected." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult1" + }, + { + "type": "nameOnly", + "name": "TResult2" + } + ] + } + } + }, + "comment": { + "shortText": "Attaches callbacks for the resolution and/or rejection of the Promise." + } + }, + "@supabase/storage-js.packages/StorageAnalyticsClient.default.constructor": { + "name": "@supabase/storage-js.packages/StorageAnalyticsClient.default.constructor", + "params": [ + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The base URL for the storage API" + } + }, + { + "name": "headers", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "comment": { + "shortText": "HTTP headers to include in requests" + } + }, + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RequestInfo" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true, + "comment": { + "shortText": "Optional custom fetch implementation" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "default" + } + }, + "comment": { + "shortText": "Creates a new StorageAnalyticsClient instance\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```typescript\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst { data, error } = await supabase.storage.analytics.listBuckets()\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```typescript\nimport { StorageAnalyticsClient } from '@supabase/storage-js'\n\nconst client = new StorageAnalyticsClient(url, headers)\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageAnalyticsClient.default.createBucket": { + "name": "@supabase/storage-js.packages/StorageAnalyticsClient.default.createBucket", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "A unique name for the bucket you are creating" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "name": "AnalyticBucket", + "properties": [ + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "ISO 8601 timestamp of bucket creation" + } + }, + { + "name": "format", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Storage format used (e.g., 'iceberg')" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Unique identifier for the bucket" + } + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "ANALYTICS" + }, + "comment": { + "shortText": "Bucket type - always 'ANALYTICS' for analytics buckets" + } + }, + { + "name": "updated_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "ISO 8601 timestamp of last update" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a new analytics bucket using Iceberg tables\nAnalytics buckets are optimized for analytical queries and data processing\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "text": "- Creates a new analytics bucket using Iceberg tables\n- Analytics buckets are optimized for analytical queries and data processing", + "examples": [ + { + "id": "create-analytics-bucket", + "name": "Create analytics bucket", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .analytics\n .createBucket('analytics-data')\n```", + "response": "```json\n{\n \"data\": {\n \"name\": \"analytics-data\",\n \"type\": \"ANALYTICS\",\n \"format\": \"iceberg\",\n \"created_at\": \"2024-05-22T22:26:05.100Z\",\n \"updated_at\": \"2024-05-22T22:26:05.100Z\"\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageAnalyticsClient.default.deleteBucket": { + "name": "@supabase/storage-js.packages/StorageAnalyticsClient.default.deleteBucket", + "params": [ + { + "name": "bucketName", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The unique identifier of the bucket you would like to delete" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Deletes an existing analytics bucket\nA bucket can't be deleted with existing objects inside it\nYou must first empty the bucket before deletion\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "text": "- Deletes an analytics bucket", + "examples": [ + { + "id": "delete-analytics-bucket", + "name": "Delete analytics bucket", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .analytics\n .deleteBucket('analytics-data')\n```", + "response": "```json\n{\n \"data\": {\n \"message\": \"Successfully deleted\"\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageAnalyticsClient.default.from": { + "name": "@supabase/storage-js.packages/StorageAnalyticsClient.default.from", + "params": [ + { + "name": "bucketName", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The name of the analytics bucket (warehouse) to connect to" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "WrappedIcebergRestCatalog" + } + }, + "comment": { + "shortText": "Get an Iceberg REST Catalog client configured for a specific analytics bucket\nUse this to perform advanced table and namespace operations within the bucket\nThe returned client provides full access to the Apache Iceberg REST Catalog API\nwith the Supabase `{ data, error }` pattern for consistent error handling on all operations.\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "text": "This method provides a bridge between Supabase's bucket management and the standard\nApache Iceberg REST Catalog API. The bucket name maps to the Iceberg warehouse parameter.\nAll authentication and configuration is handled automatically using your Supabase credentials.\n\n**Error Handling**: Invalid bucket names throw immediately. All catalog\noperations return `{ data, error }` where errors are `IcebergError` instances from iceberg-js.\nUse helper methods like `error.isNotFound()` or check `error.status` for specific error handling.\nUse `.throwOnError()` on the analytics client if you prefer exceptions for catalog operations.\n\n**Cleanup Operations**: When using `dropTable`, the `purge: true` option permanently\ndeletes all table data. Without it, the table is marked as deleted but data remains.\n\n**Library Dependency**: The returned catalog wraps `IcebergRestCatalog` from iceberg-js.\nFor complete API documentation and advanced usage, refer to the\n[iceberg-js documentation](https://supabase.github.io/iceberg-js/).", + "examples": [ + { + "id": "get-catalog-and-create-table", + "name": "Get catalog and create table", + "code": "```js\n// First, create an analytics bucket\nconst { data: bucket, error: bucketError } = await supabase\n .storage\n .analytics\n .createBucket('analytics-data')\n\n// Get the Iceberg catalog for that bucket\nconst catalog = supabase.storage.analytics.from('analytics-data')\n\n// Create a namespace\nconst { error: nsError } = await catalog.createNamespace({ namespace: ['default'] })\n\n// Create a table with schema\nconst { data: tableMetadata, error: tableError } = await catalog.createTable(\n { namespace: ['default'] },\n {\n name: 'events',\n schema: {\n type: 'struct',\n fields: [\n { id: 1, name: 'id', type: 'long', required: true },\n { id: 2, name: 'timestamp', type: 'timestamp', required: true },\n { id: 3, name: 'user_id', type: 'string', required: false }\n ],\n 'schema-id': 0,\n 'identifier-field-ids': [1]\n },\n 'partition-spec': {\n 'spec-id': 0,\n fields: []\n },\n 'write-order': {\n 'order-id': 0,\n fields: []\n },\n properties: {\n 'write.format.default': 'parquet'\n }\n }\n)\n```" + }, + { + "id": "list-tables-in-namespace", + "name": "List tables in namespace", + "code": "```js\nconst catalog = supabase.storage.analytics.from('analytics-data')\n\n// List all tables in the default namespace\nconst { data: tables, error: listError } = await catalog.listTables({ namespace: ['default'] })\nif (listError) {\n if (listError.isNotFound()) {\n console.log('Namespace not found')\n }\n return\n}\nconsole.log(tables) // [{ namespace: ['default'], name: 'events' }]\n```" + }, + { + "id": "working-with-namespaces", + "name": "Working with namespaces", + "code": "```js\nconst catalog = supabase.storage.analytics.from('analytics-data')\n\n// List all namespaces\nconst { data: namespaces } = await catalog.listNamespaces()\n\n// Create namespace with properties\nawait catalog.createNamespace(\n { namespace: ['production'] },\n { properties: { owner: 'data-team', env: 'prod' } }\n)\n```" + }, + { + "id": "cleanup-operations", + "name": "Cleanup operations", + "code": "```js\nconst catalog = supabase.storage.analytics.from('analytics-data')\n\n// Drop table with purge option (removes all data)\nconst { error: dropError } = await catalog.dropTable(\n { namespace: ['default'], name: 'events' },\n { purge: true }\n)\n\nif (dropError?.isNotFound()) {\n console.log('Table does not exist')\n}\n\n// Drop namespace (must be empty)\nawait catalog.dropNamespace({ namespace: ['default'] })\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageAnalyticsClient.default.listBuckets": { + "name": "@supabase/storage-js.packages/StorageAnalyticsClient.default.listBuckets", + "params": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "limit", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "Maximum number of buckets to return" + } + }, + { + "name": "offset", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "Number of buckets to skip" + } + }, + { + "name": "search", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Search term to filter bucket names" + } + }, + { + "name": "sortColumn", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "name" + }, + { + "type": "literal", + "value": "created_at" + }, + { + "type": "literal", + "value": "updated_at" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Column to sort by ('name', 'created_at', 'updated_at')" + } + }, + { + "name": "sortOrder", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "asc" + }, + { + "type": "literal", + "value": "desc" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Sort order ('asc' or 'desc')" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Query parameters for listing buckets" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "AnalyticBucket", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "comment": { + "shortText": "ISO 8601 timestamp of bucket creation" + } + }, + { + "name": "format", + "type": "[Circular]", + "comment": { + "shortText": "Storage format used (e.g., 'iceberg')" + } + }, + { + "name": "name", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier for the bucket" + } + }, + { + "name": "type", + "type": "[Circular]", + "comment": { + "shortText": "Bucket type - always 'ANALYTICS' for analytics buckets" + } + }, + { + "name": "updated_at", + "type": "[Circular]", + "comment": { + "shortText": "ISO 8601 timestamp of last update" + } + } + ] + } + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Retrieves the details of all Analytics Storage buckets within an existing project\nOnly returns buckets of type 'ANALYTICS'\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "text": "- Retrieves the details of all Analytics Storage buckets within an existing project\n- Only returns buckets of type 'ANALYTICS'", + "examples": [ + { + "id": "list-analytics-buckets", + "name": "List analytics buckets", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .analytics\n .listBuckets({\n limit: 10,\n offset: 0,\n sortColumn: 'created_at',\n sortOrder: 'desc'\n })\n```", + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"analytics-data\",\n \"type\": \"ANALYTICS\",\n \"format\": \"iceberg\",\n \"created_at\": \"2024-05-22T22:26:05.100Z\",\n \"updated_at\": \"2024-05-22T22:26:05.100Z\"\n }\n ],\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageAnalyticsClient.default.setHeader": { + "name": "@supabase/storage-js.packages/StorageAnalyticsClient.default.setHeader", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Header name" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Header value" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set an HTTP header for the request.\nCreates a shallow copy of headers to avoid mutating shared state." + } + }, + "@supabase/storage-js.packages/StorageAnalyticsClient.default.throwOnError": { + "name": "@supabase/storage-js.packages/StorageAnalyticsClient.default.throwOnError", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Enable throwing errors instead of returning them.\nWhen enabled, errors are thrown instead of returned in { data, error } format." + } + }, + "@supabase/storage-js.packages/StorageBucketApi.default.constructor": { + "name": "@supabase/storage-js.packages/StorageBucketApi.default.constructor", + "params": [ + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "headers", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + } + }, + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RequestInfo" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true + }, + { + "name": "opts", + "type": { + "type": "object", + "name": "StorageClientOptions", + "properties": [ + { + "name": "useNewHostname", + "type": "[Circular]", + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "default" + } + } + }, + "@supabase/storage-js.packages/StorageBucketApi.default.createBucket": { + "name": "@supabase/storage-js.packages/StorageBucketApi.default.createBucket", + "params": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "A unique identifier for the bucket you are creating." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "allowedMimeTypes", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "specifies the allowed mime types that this bucket can accept during upload.\nThe default value is null, which allows files with all mime types to be uploaded.\nEach mime type specified can be a wildcard, e.g. image/*, or a specific mime type, e.g. image/png." + } + }, + { + "name": "fileSizeLimit", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "specifies the max file size in bytes that can be uploaded to this bucket.\nThe global file size limit takes precedence over this value.\nThe default value is null, which doesn't set a per bucket file size limit." + } + }, + { + "name": "public", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "comment": { + "shortText": "The visibility of the bucket. Public buckets don't require an authorization token to download objects, but still require a valid token for all other operations. By default, buckets are private." + } + }, + { + "name": "type", + "type": { + "type": "union", + "name": "BucketType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + }, + "isOptional": true, + "comment": { + "shortText": "(private-beta) specifies the bucket type. see `BucketType` for more details.\n - default bucket type is `STANDARD`" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a new Storage bucket", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: `insert`\n - `objects` table permissions: none\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "create-bucket", + "name": "Create bucket", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .createBucket('avatars', {\n public: false,\n allowedMimeTypes: ['image/png'],\n fileSizeLimit: 1024\n })\n```", + "response": "```json\n{\n \"data\": {\n \"name\": \"avatars\"\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageBucketApi.default.deleteBucket": { + "name": "@supabase/storage-js.packages/StorageBucketApi.default.deleteBucket", + "params": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The unique identifier of the bucket you would like to delete." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Deletes an existing bucket. A bucket can't be deleted with existing objects inside it.\nYou must first `empty()` the bucket.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: `select` and `delete`\n - `objects` table permissions: none\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "delete-bucket", + "name": "Delete bucket", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .deleteBucket('avatars')\n```", + "response": "```json\n{\n \"data\": {\n \"message\": \"Successfully deleted\"\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageBucketApi.default.emptyBucket": { + "name": "@supabase/storage-js.packages/StorageBucketApi.default.emptyBucket", + "params": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The unique identifier of the bucket you would like to empty." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Removes all objects inside a single bucket.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: `select`\n - `objects` table permissions: `select` and `delete`\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "empty-bucket", + "name": "Empty bucket", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .emptyBucket('avatars')\n```", + "response": "```json\n{\n \"data\": {\n \"message\": \"Successfully emptied\"\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageBucketApi.default.getBucket": { + "name": "@supabase/storage-js.packages/StorageBucketApi.default.getBucket", + "params": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The unique identifier of the bucket you would like to retrieve." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "name": "Bucket", + "properties": [ + { + "name": "allowed_mime_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "file_size_limit", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "name", + "type": "[Circular]" + }, + { + "name": "owner", + "type": "[Circular]" + }, + { + "name": "public", + "type": "[Circular]" + }, + { + "name": "type", + "type": { + "type": "union", + "name": "BucketType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + }, + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Retrieves the details of an existing Storage bucket.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: `select`\n - `objects` table permissions: none\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "get-bucket", + "name": "Get bucket", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .getBucket('avatars')\n```", + "response": "```json\n{\n \"data\": {\n \"id\": \"avatars\",\n \"name\": \"avatars\",\n \"owner\": \"\",\n \"public\": false,\n \"file_size_limit\": 1024,\n \"allowed_mime_types\": [\n \"image/png\"\n ],\n \"created_at\": \"2024-05-22T22:26:05.100Z\",\n \"updated_at\": \"2024-05-22T22:26:05.100Z\"\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageBucketApi.default.listBuckets": { + "name": "@supabase/storage-js.packages/StorageBucketApi.default.listBuckets", + "params": [ + { + "name": "options", + "type": { + "type": "object", + "name": "ListBucketOptions", + "properties": [ + { + "name": "limit", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "offset", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "search", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "sortColumn", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true + }, + { + "name": "sortOrder", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Query parameters for listing buckets" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "Bucket", + "properties": [ + { + "name": "allowed_mime_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "file_size_limit", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "name", + "type": "[Circular]" + }, + { + "name": "owner", + "type": "[Circular]" + }, + { + "name": "public", + "type": "[Circular]" + }, + { + "name": "type", + "type": { + "type": "union", + "name": "BucketType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + }, + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Retrieves the details of all Storage buckets within an existing project.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: `select`\n - `objects` table permissions: none\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "list-buckets", + "name": "List buckets", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .listBuckets()\n```" + }, + { + "id": "list-buckets-with-options", + "name": "List buckets with options", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .listBuckets({\n limit: 10,\n offset: 0,\n sortColumn: 'created_at',\n sortOrder: 'desc',\n search: 'prod'\n })\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageBucketApi.default.setHeader": { + "name": "@supabase/storage-js.packages/StorageBucketApi.default.setHeader", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Header name" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Header value" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set an HTTP header for the request.\nCreates a shallow copy of headers to avoid mutating shared state." + } + }, + "@supabase/storage-js.packages/StorageBucketApi.default.throwOnError": { + "name": "@supabase/storage-js.packages/StorageBucketApi.default.throwOnError", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Enable throwing errors instead of returning them.\nWhen enabled, errors are thrown instead of returned in { data, error } format." + } + }, + "@supabase/storage-js.packages/StorageBucketApi.default.updateBucket": { + "name": "@supabase/storage-js.packages/StorageBucketApi.default.updateBucket", + "params": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "A unique identifier for the bucket you are updating." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "allowedMimeTypes", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "specifies the allowed mime types that this bucket can accept during upload.\nThe default value is null, which allows files with all mime types to be uploaded.\nEach mime type specified can be a wildcard, e.g. image/*, or a specific mime type, e.g. image/png." + } + }, + { + "name": "fileSizeLimit", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "specifies the max file size in bytes that can be uploaded to this bucket.\nThe global file size limit takes precedence over this value.\nThe default value is null, which doesn't set a per bucket file size limit." + } + }, + { + "name": "public", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "comment": { + "shortText": "The visibility of the bucket. Public buckets don't require an authorization token to download objects, but still require a valid token for all other operations." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Updates a Storage bucket", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: `select` and `update`\n - `objects` table permissions: none\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "update-bucket", + "name": "Update bucket", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .updateBucket('avatars', {\n public: false,\n allowedMimeTypes: ['image/png'],\n fileSizeLimit: 1024\n })\n```", + "response": "```json\n{\n \"data\": {\n \"message\": \"Successfully updated\"\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.constructor": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.constructor", + "params": [ + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "headers", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + } + }, + { + "name": "bucketId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RequestInfo" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "default" + } + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.copy": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.copy", + "params": [ + { + "name": "fromPath", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The original file path, including the current file name. For example `folder/image.png`." + } + }, + { + "name": "toPath", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The new file path, including the new file name. For example `folder/image-copy.png`." + } + }, + { + "name": "options", + "type": { + "type": "object", + "name": "DestinationOptions", + "properties": [ + { + "name": "destinationBucket", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The destination options." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "path", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Copies an existing file to a new path in the same bucket.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: none\n - `objects` table permissions: `insert` and `select`\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "copy-file", + "name": "Copy file", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .copy('public/avatar1.png', 'private/avatar2.png')\n```", + "response": "```json\n{\n \"data\": {\n \"path\": \"avatars/private/avatar2.png\"\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.createSignedUploadUrl": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.createSignedUploadUrl", + "params": [ + { + "name": "path", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The file path, including the current file name. For example `folder/image.png`." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "upsert", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "comment": { + "shortText": "If set to true, allows the file to be overwritten if it already exists." + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "path", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "signedUrl", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "token", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a signed upload URL.\nSigned upload URLs can be used to upload files to the bucket without further authentication.\nThey are valid for 2 hours.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: none\n - `objects` table permissions: `insert`\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "create-signed-upload-url", + "name": "Create Signed Upload URL", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .createSignedUploadUrl('folder/cat.jpg')\n```", + "response": "```json\n{\n \"data\": {\n \"signedUrl\": \"https://example.supabase.co/storage/v1/object/upload/sign/avatars/folder/cat.jpg?token=\",\n \"path\": \"folder/cat.jpg\",\n \"token\": \"\"\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.createSignedUrl": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.createSignedUrl", + "params": [ + { + "name": "path", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The file path, including the current file name. For example `folder/image.png`." + } + }, + { + "name": "expiresIn", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The number of seconds until the signed URL expires. For example, `60` for a URL which is valid for one minute." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "cacheNonce", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Append a cache nonce parameter to the URL to invalidate the cache." + } + }, + { + "name": "download", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "boolean" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "triggers the file as a download if set to true. Set this parameter as the name of the file if you want to trigger the download with a different filename." + } + }, + { + "name": "transform", + "type": { + "type": "object", + "name": "TransformOptions", + "properties": [ + { + "name": "format", + "type": { + "type": "literal", + "value": "origin" + }, + "isOptional": true, + "comment": { + "shortText": "Specify the format of the image requested.\n\nWhen using 'origin' we force the format to be the same as the original image.\nWhen this option is not passed in, images are optimized to modern image formats like Webp." + } + }, + { + "name": "height", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "The height of the image in pixels." + } + }, + { + "name": "quality", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "Set the quality of the returned image.\nA number from 20 to 100, with 100 being the highest quality.\nDefaults to 80" + } + }, + { + "name": "resize", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "cover" + }, + { + "type": "literal", + "value": "contain" + }, + { + "type": "literal", + "value": "fill" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The resize mode can be cover, contain or fill. Defaults to cover.\nCover resizes the image to maintain it's aspect ratio while filling the entire width and height.\nContain resizes the image to maintain it's aspect ratio while fitting the entire image within the width and height.\nFill resizes the image to fill the entire width and height. If the object's aspect ratio does not match the width and height, the image will be stretched to fit." + } + }, + { + "name": "width", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "The width of the image in pixels." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Transform the asset before serving it to the client." + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "signedUrl", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a signed URL. Use a signed URL to share a file for a fixed amount of time.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: none\n - `objects` table permissions: `select`\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "create-signed-url", + "name": "Create Signed URL", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .createSignedUrl('folder/avatar1.png', 60)\n```", + "response": "```json\n{\n \"data\": {\n \"signedUrl\": \"https://example.supabase.co/storage/v1/object/sign/avatars/folder/avatar1.png?token=\"\n },\n \"error\": null\n}\n```" + }, + { + "id": "create-a-signed-url-for-an-asset-with-transformations", + "name": "Create a signed URL for an asset with transformations", + "code": "```js\nconst { data } = await supabase\n .storage\n .from('avatars')\n .createSignedUrl('folder/avatar1.png', 60, {\n transform: {\n width: 100,\n height: 100,\n }\n })\n```" + }, + { + "id": "create-a-signed-url-which-triggers-the-download-of-the-asset", + "name": "Create a signed URL which triggers the download of the asset", + "code": "```js\nconst { data } = await supabase\n .storage\n .from('avatars')\n .createSignedUrl('folder/avatar1.png', 60, {\n download: true,\n })\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.createSignedUrls": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.createSignedUrls", + "params": [ + { + "name": "paths", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "comment": { + "shortText": "The file paths to be downloaded, including the current file names. For example `['folder/image.png', 'folder2/image2.png']`." + } + }, + { + "name": "expiresIn", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The number of seconds until the signed URLs expire. For example, `60` for URLs which are valid for one minute." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "cacheNonce", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Append a cache nonce parameter to the URL to invalidate the cache." + } + }, + { + "name": "download", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "boolean" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "triggers the file as a download if set to true. Set this parameter as the name of the file if you want to trigger the download with a different filename." + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "array", + "elemType": { + "type": "object", + "properties": [ + { + "name": "error", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "name": "path", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "name": "signedUrl", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ] + } + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates multiple signed URLs. Use a signed URL to share a file for a fixed amount of time.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: none\n - `objects` table permissions: `select`\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "create-signed-urls", + "name": "Create Signed URLs", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .createSignedUrls(['folder/avatar1.png', 'folder/avatar2.png'], 60)\n```", + "response": "```json\n{\n \"data\": [\n {\n \"error\": null,\n \"path\": \"folder/avatar1.png\",\n \"signedURL\": \"/object/sign/avatars/folder/avatar1.png?token=\",\n \"signedUrl\": \"https://example.supabase.co/storage/v1/object/sign/avatars/folder/avatar1.png?token=\"\n },\n {\n \"error\": null,\n \"path\": \"folder/avatar2.png\",\n \"signedURL\": \"/object/sign/avatars/folder/avatar2.png?token=\",\n \"signedUrl\": \"https://example.supabase.co/storage/v1/object/sign/avatars/folder/avatar2.png?token=\"\n }\n ],\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.download": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.download", + "params": [ + { + "name": "path", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The full path and file name of the file to be downloaded. For example `folder/image.png`." + } + }, + { + "name": "options", + "type": { + "type": "nameOnly", + "name": "Options" + }, + "isOptional": true + }, + { + "name": "parameters", + "type": { + "type": "object", + "name": "FetchParameters", + "properties": [ + { + "name": "cache", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "default" + }, + { + "type": "literal", + "value": "no-store" + }, + { + "type": "literal", + "value": "reload" + }, + { + "type": "literal", + "value": "no-cache" + }, + { + "type": "literal", + "value": "force-cache" + }, + { + "type": "literal", + "value": "only-if-cached" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Controls how the request interacts with the browser's HTTP cache.\n- 'default': Use standard cache behavior\n- 'no-store': Bypass cache entirely (useful in Edge Functions)\n- 'reload': Bypass cache but update it with response\n- 'no-cache': Validate with server before using cached response\n- 'force-cache': Use cache even if stale\n- 'only-if-cached': Only use cache, fail if not cached" + } + }, + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "isOptional": true, + "comment": { + "shortText": "Pass in an AbortController's signal to cancel the request." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Additional fetch parameters like signal for cancellation. Supports standard fetch options including cache control." + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "default" + } + }, + "comment": { + "shortText": "Downloads a file from a private bucket. For public buckets, make a request to the URL returned from `getPublicUrl` instead.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: none\n - `objects` table permissions: `select`\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "download-file", + "name": "Download file", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .download('folder/avatar1.png')\n```", + "response": "```json\n{\n \"data\": ,\n \"error\": null\n}\n```" + }, + { + "id": "download-file-with-transformations", + "name": "Download file with transformations", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .download('folder/avatar1.png', {\n transform: {\n width: 100,\n height: 100,\n quality: 80\n }\n })\n```" + }, + { + "id": "download-with-cache-control-useful-in-edge-functions", + "name": "Download with cache control (useful in Edge Functions)", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .download('folder/avatar1.png', {}, { cache: 'no-store' })\n```" + }, + { + "id": "download-with-abort-signal", + "name": "Download with abort signal", + "code": "```js\nconst controller = new AbortController()\nsetTimeout(() => controller.abort(), 5000)\n\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .download('folder/avatar1.png', {}, { signal: controller.signal })\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.exists": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.exists", + "params": [ + { + "name": "path", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The file path, including the file name. For example `folder/image.png`." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "boolean" + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "boolean" + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Checks the existence of a file.", + "examples": [ + { + "id": "check-file-existence", + "name": "Check file existence", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .exists('folder/avatar1.png')\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.getPublicUrl": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.getPublicUrl", + "params": [ + { + "name": "path", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The path and name of the file to generate the public URL for. For example `folder/image.png`." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "cacheNonce", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Append a cache nonce parameter to the URL to invalidate the cache." + } + }, + { + "name": "download", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "boolean" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Triggers the file as a download if set to true. Set this parameter as the name of the file if you want to trigger the download with a different filename." + } + }, + { + "name": "transform", + "type": { + "type": "object", + "name": "TransformOptions", + "properties": [ + { + "name": "format", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Specify the format of the image requested.\n\nWhen using 'origin' we force the format to be the same as the original image.\nWhen this option is not passed in, images are optimized to modern image formats like Webp." + } + }, + { + "name": "height", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The height of the image in pixels." + } + }, + { + "name": "quality", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Set the quality of the returned image.\nA number from 20 to 100, with 100 being the highest quality.\nDefaults to 80" + } + }, + { + "name": "resize", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The resize mode can be cover, contain or fill. Defaults to cover.\nCover resizes the image to maintain it's aspect ratio while filling the entire width and height.\nContain resizes the image to maintain it's aspect ratio while fitting the entire image within the width and height.\nFill resizes the image to fill the entire width and height. If the object's aspect ratio does not match the width and height, the image will be stretched to fit." + } + }, + { + "name": "width", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The width of the image in pixels." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Transform the asset before serving it to the client." + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "publicUrl", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + ] + } + }, + "comment": { + "shortText": "A simple convenience function to get the URL for an asset in a public bucket. If you do not want to use this function, you can construct the public URL by concatenating the bucket URL with the path to the asset.\nThis function does not verify if the bucket is public. If a public URL is created for a bucket which is not public, you will not be able to download the asset.", + "text": "- The bucket needs to be set to public, either via [updateBucket()](/docs/reference/javascript/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing \"Make public\"\n- RLS policy permissions required:\n - `buckets` table permissions: none\n - `objects` table permissions: none\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "returns-the-url-for-an-asset-in-a-public-bucket", + "name": "Returns the URL for an asset in a public bucket", + "code": "```js\nconst { data } = supabase\n .storage\n .from('public-bucket')\n .getPublicUrl('folder/avatar1.png')\n```", + "response": "```json\n{\n \"data\": {\n \"publicUrl\": \"https://example.supabase.co/storage/v1/object/public/public-bucket/folder/avatar1.png\"\n }\n}\n```" + }, + { + "id": "returns-the-url-for-an-asset-in-a-public-bucket-with-transformations", + "name": "Returns the URL for an asset in a public bucket with transformations", + "code": "```js\nconst { data } = supabase\n .storage\n .from('public-bucket')\n .getPublicUrl('folder/avatar1.png', {\n transform: {\n width: 100,\n height: 100,\n }\n })\n```" + }, + { + "id": "returns-the-url-which-triggers-the-download-of-an-asset-in-a-public-bucket", + "name": "Returns the URL which triggers the download of an asset in a public bucket", + "code": "```js\nconst { data } = supabase\n .storage\n .from('public-bucket')\n .getPublicUrl('folder/avatar1.png', {\n download: true,\n })\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.info": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.info", + "params": [ + { + "name": "path", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The file path, including the file name. For example `folder/image.png`." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "nameOnly", + "name": "Camelize" + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Retrieves the details of an existing file.\n\nReturns detailed file metadata including size, content type, and timestamps.\nNote: The API returns `last_modified` field, not `updated_at`.", + "examples": [ + { + "id": "get-file-info", + "name": "Get file info", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .info('folder/avatar1.png')\n\nif (data) {\n console.log('Last modified:', data.lastModified)\n console.log('Size:', data.size)\n}\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.list": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.list", + "params": [ + { + "name": "path", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The folder path." + } + }, + { + "name": "options", + "type": { + "type": "object", + "name": "SearchOptions", + "properties": [ + { + "name": "limit", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "The number of files you want to be returned." + } + }, + { + "name": "offset", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "The starting position." + } + }, + { + "name": "search", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The search string to filter files by." + } + }, + { + "name": "sortBy", + "type": { + "type": "object", + "name": "SortBy", + "properties": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "order", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The column to sort by. Can be any column inside a FileObject." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Search options including limit (defaults to 100), offset, sortBy, and search" + } + }, + { + "name": "parameters", + "type": { + "type": "object", + "name": "FetchParameters", + "properties": [ + { + "name": "cache", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "Controls how the request interacts with the browser's HTTP cache.\n- 'default': Use standard cache behavior\n- 'no-store': Bypass cache entirely (useful in Edge Functions)\n- 'reload': Bypass cache but update it with response\n- 'no-cache': Validate with server before using cached response\n- 'force-cache': Use cache even if stale\n- 'only-if-cached': Only use cache, fail if not cached" + } + }, + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "isOptional": true, + "comment": { + "shortText": "Pass in an AbortController's signal to cancel the request." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Optional fetch parameters including signal for cancellation" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "FileObject", + "properties": [ + { + "name": "bucket_id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "" + } + }, + { + "name": "buckets", + "type": { + "type": "object", + "name": "Bucket", + "properties": [ + { + "name": "allowed_mime_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "file_size_limit", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "name", + "type": "[Circular]" + }, + { + "name": "owner", + "type": "[Circular]" + }, + { + "name": "public", + "type": "[Circular]" + }, + { + "name": "type", + "type": { + "type": "union", + "name": "BucketType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + }, + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "" + } + }, + { + "name": "created_at", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "comment": { + "shortText": "Creation timestamp (null for folders)" + } + }, + { + "name": "id", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "comment": { + "shortText": "Unique identifier for the file (null for folders)" + } + }, + { + "name": "last_accessed_at", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "comment": { + "shortText": "" + } + }, + { + "name": "metadata", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "object", + "name": "FileMetadata", + "properties": [ + { + "name": "cacheControl", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Cache control directive (e.g., \"max-age=3600\")" + } + }, + { + "name": "contentLength", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "Content length in bytes (usually same as size)" + } + }, + { + "name": "eTag", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Entity tag for caching and conditional requests" + } + }, + { + "name": "httpStatusCode", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "HTTP status code from the storage backend" + } + }, + { + "name": "lastModified", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Last modification timestamp (ISO 8601)" + } + }, + { + "name": "mimetype", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "MIME type of the file" + } + }, + { + "name": "size", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "File size in bytes" + } + } + ] + } + ] + }, + "comment": { + "shortText": "File metadata including size, mimetype, etc. (null for folders)" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "File or folder name (relative to the prefix) - always present" + } + }, + { + "name": "owner", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "" + } + }, + { + "name": "updated_at", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "comment": { + "shortText": "Last update timestamp (null for folders)" + } + } + ] + } + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists all the files and folders within a path of the bucket.\n\n**Important:** For folder entries, fields like `id`, `updated_at`, `created_at`,\n`last_accessed_at`, and `metadata` will be `null`. Only files have these fields populated.\nAdditionally, deprecated fields like `bucket_id`, `owner`, and `buckets` are NOT returned\nby this method.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: none\n - `objects` table permissions: `select`\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "list-files-in-a-bucket", + "name": "List files in a bucket", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .list('folder', {\n limit: 100,\n offset: 0,\n sortBy: { column: 'name', order: 'asc' },\n })\n\n// Handle files vs folders\ndata?.forEach(item => {\n if (item.id !== null) {\n // It's a file\n console.log('File:', item.name, 'Size:', item.metadata?.size)\n } else {\n // It's a folder\n console.log('Folder:', item.name)\n }\n})\n```", + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"avatar1.png\",\n \"id\": \"e668cf7f-821b-4a2f-9dce-7dfa5dd1cfd2\",\n \"updated_at\": \"2024-05-22T23:06:05.580Z\",\n \"created_at\": \"2024-05-22T23:04:34.443Z\",\n \"last_accessed_at\": \"2024-05-22T23:04:34.443Z\",\n \"metadata\": {\n \"eTag\": \"\\\"c5e8c553235d9af30ef4f6e280790b92\\\"\",\n \"size\": 32175,\n \"mimetype\": \"image/png\",\n \"cacheControl\": \"max-age=3600\",\n \"lastModified\": \"2024-05-22T23:06:05.574Z\",\n \"contentLength\": 32175,\n \"httpStatusCode\": 200\n }\n }\n ],\n \"error\": null\n}\n```" + }, + { + "id": "search-files-in-a-bucket", + "name": "Search files in a bucket", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .list('folder', {\n limit: 100,\n offset: 0,\n sortBy: { column: 'name', order: 'asc' },\n search: 'jon'\n })\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.listV2": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.listV2", + "params": [ + { + "name": "options", + "type": { + "type": "object", + "name": "SearchV2Options", + "properties": [ + { + "name": "cursor", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The cursor used for pagination. Pass the value received from nextCursor of the previous request." + } + }, + { + "name": "limit", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "The number of files you want to be returned." + } + }, + { + "name": "prefix", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The prefix search string to filter files by." + } + }, + { + "name": "sortBy", + "type": { + "type": "object", + "name": "SortByV2", + "properties": [ + { + "name": "column", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "name" + }, + { + "type": "literal", + "value": "created_at" + }, + { + "type": "literal", + "value": "updated_at" + } + ] + } + }, + { + "name": "order", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "asc" + }, + { + "type": "literal", + "value": "desc" + } + ] + }, + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The column and order to sort by" + } + }, + { + "name": "with_delimiter", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether to emulate a hierarchical listing of objects using delimiters.\n\n- When `false` (default), all objects are listed as flat key/value pairs.\n- When `true`, the response groups objects by delimiter, making it appear\n like a file/folder hierarchy." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Search options including prefix, cursor for pagination, limit, with_delimiter" + } + }, + { + "name": "parameters", + "type": { + "type": "object", + "name": "FetchParameters", + "properties": [ + { + "name": "cache", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "Controls how the request interacts with the browser's HTTP cache.\n- 'default': Use standard cache behavior\n- 'no-store': Bypass cache entirely (useful in Edge Functions)\n- 'reload': Bypass cache but update it with response\n- 'no-cache': Validate with server before using cached response\n- 'force-cache': Use cache even if stale\n- 'only-if-cached': Only use cache, fail if not cached" + } + }, + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "isOptional": true, + "comment": { + "shortText": "Pass in an AbortController's signal to cancel the request." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Optional fetch parameters including signal for cancellation" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "name": "SearchV2Result", + "properties": [ + { + "name": "folders", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "SearchV2Folder", + "properties": [ + { + "name": "key", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Full folder key/path" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Folder name/prefix" + } + } + ] + } + } + }, + { + "name": "hasNext", + "type": { + "type": "intrinsic", + "name": "boolean" + } + }, + { + "name": "nextCursor", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "objects", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "SearchV2Object", + "properties": [ + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Creation timestamp" + } + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Unique identifier for the file" + } + }, + { + "name": "key", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Full object key/path" + } + }, + { + "name": "last_accessed_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "" + } + }, + { + "name": "metadata", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "object", + "name": "FileMetadata", + "properties": [ + { + "name": "cacheControl", + "type": "[Circular]", + "comment": { + "shortText": "Cache control directive (e.g., \"max-age=3600\")" + } + }, + { + "name": "contentLength", + "type": "[Circular]", + "comment": { + "shortText": "Content length in bytes (usually same as size)" + } + }, + { + "name": "eTag", + "type": "[Circular]", + "comment": { + "shortText": "Entity tag for caching and conditional requests" + } + }, + { + "name": "httpStatusCode", + "type": "[Circular]", + "comment": { + "shortText": "HTTP status code from the storage backend" + } + }, + { + "name": "lastModified", + "type": "[Circular]", + "comment": { + "shortText": "Last modification timestamp (ISO 8601)" + } + }, + { + "name": "mimetype", + "type": "[Circular]", + "comment": { + "shortText": "MIME type of the file" + } + }, + { + "name": "size", + "type": "[Circular]", + "comment": { + "shortText": "File size in bytes" + } + } + ] + } + ] + }, + "comment": { + "shortText": "File metadata including size, mimetype, etc. (null if not yet set)" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "File name" + } + }, + { + "name": "updated_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Last update timestamp" + } + } + ] + } + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists all the files and folders within a bucket using the V2 API with pagination support.\n\n**Important:** Folder entries in the `folders` array only contain `name` and optionally `key` —\nthey have no `id`, timestamps, or `metadata` fields. Full file metadata is only available\non entries in the `objects` array.\n\n this method signature might change in the future", + "tags": [ + { + "tag": "experimental", + "text": "" + } + ], + "examples": [ + { + "id": "list-files-with-pagination", + "name": "List files with pagination", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .listV2({\n prefix: 'folder/',\n limit: 100,\n })\n\n// Handle pagination\nif (data?.hasNext) {\n const nextPage = await supabase\n .storage\n .from('avatars')\n .listV2({\n prefix: 'folder/',\n cursor: data.nextCursor,\n })\n}\n\n// Handle files vs folders\ndata?.objects.forEach(file => {\n if (file.id !== null) {\n console.log('File:', file.name, 'Size:', file.metadata?.size)\n }\n})\ndata?.folders.forEach(folder => {\n console.log('Folder:', folder.name)\n})\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.move": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.move", + "params": [ + { + "name": "fromPath", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The original file path, including the current file name. For example `folder/image.png`." + } + }, + { + "name": "toPath", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The new file path, including the new file name. For example `folder/image-new.png`." + } + }, + { + "name": "options", + "type": { + "type": "object", + "name": "DestinationOptions", + "properties": [ + { + "name": "destinationBucket", + "type": "[Circular]", + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The destination options." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Moves an existing file to a new path in the same bucket.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: none\n - `objects` table permissions: `update` and `select`\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "move-file", + "name": "Move file", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .move('public/avatar1.png', 'private/avatar2.png')\n```", + "response": "```json\n{\n \"data\": {\n \"message\": \"Successfully moved\"\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.remove": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.remove", + "params": [ + { + "name": "paths", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "comment": { + "shortText": "An array of files to delete, including the path and file name. For example [`'folder/image.png'`]." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "FileObject", + "properties": [ + { + "name": "bucket_id", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "" + } + }, + { + "name": "buckets", + "type": { + "type": "object", + "name": "Bucket", + "properties": [ + { + "name": "allowed_mime_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "file_size_limit", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "name", + "type": "[Circular]" + }, + { + "name": "owner", + "type": "[Circular]" + }, + { + "name": "public", + "type": "[Circular]" + }, + { + "name": "type", + "type": { + "type": "union", + "name": "BucketType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + }, + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "" + } + }, + { + "name": "created_at", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Creation timestamp (null for folders)" + } + }, + { + "name": "id", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Unique identifier for the file (null for folders)" + } + }, + { + "name": "last_accessed_at", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "" + } + }, + { + "name": "metadata", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + { + "type": "object", + "name": "FileMetadata", + "properties": [ + { + "name": "cacheControl", + "type": "[Circular]", + "comment": { + "shortText": "Cache control directive (e.g., \"max-age=3600\")" + } + }, + { + "name": "contentLength", + "type": "[Circular]", + "comment": { + "shortText": "Content length in bytes (usually same as size)" + } + }, + { + "name": "eTag", + "type": "[Circular]", + "comment": { + "shortText": "Entity tag for caching and conditional requests" + } + }, + { + "name": "httpStatusCode", + "type": "[Circular]", + "comment": { + "shortText": "HTTP status code from the storage backend" + } + }, + { + "name": "lastModified", + "type": "[Circular]", + "comment": { + "shortText": "Last modification timestamp (ISO 8601)" + } + }, + { + "name": "mimetype", + "type": "[Circular]", + "comment": { + "shortText": "MIME type of the file" + } + }, + { + "name": "size", + "type": "[Circular]", + "comment": { + "shortText": "File size in bytes" + } + } + ] + } + ] + }, + "comment": { + "shortText": "File metadata including size, mimetype, etc. (null for folders)" + } + }, + { + "name": "name", + "type": "[Circular]", + "comment": { + "shortText": "File or folder name (relative to the prefix) - always present" + } + }, + { + "name": "owner", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "" + } + }, + { + "name": "updated_at", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Last update timestamp (null for folders)" + } + } + ] + } + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Deletes files within the same bucket\n\nReturns an array of FileObject entries for the deleted files. Note that deprecated\nfields like `bucket_id` may or may not be present in the response - do not rely on them.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: none\n - `objects` table permissions: `delete` and `select`\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "delete-file", + "name": "Delete file", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .remove(['folder/avatar1.png'])\n```", + "response": "```json\n{\n \"data\": [],\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.setHeader": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.setHeader", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Header name" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Header value" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set an HTTP header for the request.\nCreates a shallow copy of headers to avoid mutating shared state." + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.throwOnError": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.throwOnError", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Enable throwing errors instead of returning them.\nWhen enabled, errors are thrown instead of returned in { data, error } format." + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.toBase64": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.toBase64", + "params": [ + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "string" + } + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.update": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.update", + "params": [ + { + "name": "path", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to update." + } + }, + { + "name": "fileBody", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "nameOnly", + "name": "ArrayBuffer" + }, + { + "type": "nameOnly", + "name": "ReadableStream" + }, + { + "type": "nameOnly", + "name": "Blob" + }, + { + "type": "nameOnly", + "name": "File" + }, + { + "type": "nameOnly", + "name": "FormData" + }, + { + "type": "nameOnly", + "name": "@types/node.__global.NodeJS.ReadableStream" + }, + { + "type": "nameOnly", + "name": "URLSearchParams" + }, + { + "type": "nameOnly", + "name": "ArrayBufferView" + }, + { + "type": "nameOnly", + "name": "@types/node.__global.Buffer" + } + ] + }, + "comment": { + "shortText": "The body of the file to be stored in the bucket." + } + }, + { + "name": "fileOptions", + "type": { + "type": "object", + "name": "FileOptions", + "properties": [ + { + "name": "cacheControl", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The number of seconds the asset is cached in the browser and in the Supabase CDN. This is set in the `Cache-Control: max-age=` header. Defaults to 3600 seconds." + } + }, + { + "name": "contentType", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "the `Content-Type` header value. Should be specified if using a `fileBody` that is neither `Blob` nor `File` nor `FormData`, otherwise will default to `text/plain;charset=UTF-8`." + } + }, + { + "name": "duplex", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The duplex option is a string parameter that enables or disables duplex streaming, allowing for both reading and writing data in the same stream. It can be passed as an option to the fetch() method." + } + }, + { + "name": "headers", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Optionally add extra headers" + } + }, + { + "name": "metadata", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + "isOptional": true, + "comment": { + "shortText": "The metadata option is an object that allows you to store additional information about the file. This information can be used to filter and search for files. The metadata object can contain any key-value pairs you want to store." + } + }, + { + "name": "upsert", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "When upsert is set to true, the file is overwritten if it exists. When set to false, an error is thrown if the object already exists. Defaults to false." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Optional file upload options including cacheControl, contentType, and metadata.\n**Note:** The `upsert` option has no effect here. `update()` always replaces the\nfile at the given path, so the `x-upsert` header is not sent. To control upsert\nbehavior, use `upload()` instead." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "fullPath", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "path", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Replaces an existing file at the specified path with a new one.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: none\n - `objects` table permissions: `update` and `select`\n- `update()` always replaces the file at the given path regardless of the `upsert` option.\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works\n- For React Native, using either `Blob`, `File` or `FormData` does not work as intended. Update file using `ArrayBuffer` from base64 file data instead, see example below.", + "examples": [ + { + "id": "update-file", + "name": "Update file", + "code": "```js\nconst avatarFile = event.target.files[0]\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .update('public/avatar1.png', avatarFile, {\n cacheControl: '3600'\n })\n```", + "response": "```json\n{\n \"data\": {\n \"path\": \"public/avatar1.png\",\n \"fullPath\": \"avatars/public/avatar1.png\"\n },\n \"error\": null\n}\n```" + }, + { + "id": "update-file-using-arraybuffer-from-base64-file-data", + "name": "Update file using `ArrayBuffer` from base64 file data", + "code": "```js\nimport {decode} from 'base64-arraybuffer'\n\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .update('public/avatar1.png', decode('base64FileData'), {\n contentType: 'image/png'\n })\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.upload": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.upload", + "params": [ + { + "name": "path", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The file path, including the file name. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload." + } + }, + { + "name": "fileBody", + "type": { + "type": "nameOnly", + "name": "FileBody" + }, + "comment": { + "shortText": "The body of the file to be stored in the bucket." + } + }, + { + "name": "fileOptions", + "type": { + "type": "object", + "name": "FileOptions", + "properties": [ + { + "name": "cacheControl", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The number of seconds the asset is cached in the browser and in the Supabase CDN. This is set in the `Cache-Control: max-age=` header. Defaults to 3600 seconds." + } + }, + { + "name": "contentType", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "the `Content-Type` header value. Should be specified if using a `fileBody` that is neither `Blob` nor `File` nor `FormData`, otherwise will default to `text/plain;charset=UTF-8`." + } + }, + { + "name": "duplex", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The duplex option is a string parameter that enables or disables duplex streaming, allowing for both reading and writing data in the same stream. It can be passed as an option to the fetch() method." + } + }, + { + "name": "headers", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Optionally add extra headers" + } + }, + { + "name": "metadata", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "The metadata option is an object that allows you to store additional information about the file. This information can be used to filter and search for files. The metadata object can contain any key-value pairs you want to store." + } + }, + { + "name": "upsert", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "When upsert is set to true, the file is overwritten if it exists. When set to false, an error is thrown if the object already exists. Defaults to false." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Optional file upload options including cacheControl, contentType, upsert, and metadata." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "fullPath", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "path", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Uploads a file to an existing bucket.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: none\n - `objects` table permissions: only `insert` when you are uploading new files and `select`, `insert` and `update` when you are upserting files\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works\n- For React Native, using either `Blob`, `File` or `FormData` does not work as intended. Upload file using `ArrayBuffer` from base64 file data instead, see example below.", + "examples": [ + { + "id": "upload-file", + "name": "Upload file", + "code": "```js\nconst avatarFile = event.target.files[0]\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .upload('public/avatar1.png', avatarFile, {\n cacheControl: '3600',\n upsert: false\n })\n```", + "response": "```json\n{\n \"data\": {\n \"path\": \"public/avatar1.png\",\n \"fullPath\": \"avatars/public/avatar1.png\"\n },\n \"error\": null\n}\n```" + }, + { + "id": "upload-file-using-arraybuffer-from-base64-file-data", + "name": "Upload file using `ArrayBuffer` from base64 file data", + "code": "```js\nimport { decode } from 'base64-arraybuffer'\n\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .upload('public/avatar1.png', decode('base64FileData'), {\n contentType: 'image/png'\n })\n```" + }, + { + "id": "handling-errors", + "name": "Handling errors", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .upload('public/avatar1.png', avatarFile)\n\nif (error) {\n // Log the full error so fields like `statusCode` and `error` (the\n // Storage error name, e.g. \"Duplicate\") aren't hidden behind `error.message`.\n console.error(error)\n return\n}\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageFileApi.default.uploadToSignedUrl": { + "name": "@supabase/storage-js.packages/StorageFileApi.default.uploadToSignedUrl", + "params": [ + { + "name": "path", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The file path, including the file name. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload." + } + }, + { + "name": "token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The token generated from `createSignedUploadUrl`" + } + }, + { + "name": "fileBody", + "type": { + "type": "nameOnly", + "name": "FileBody" + }, + "comment": { + "shortText": "The body of the file to be stored in the bucket." + } + }, + { + "name": "fileOptions", + "type": { + "type": "object", + "name": "FileOptions", + "properties": [ + { + "name": "cacheControl", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The number of seconds the asset is cached in the browser and in the Supabase CDN. This is set in the `Cache-Control: max-age=` header. Defaults to 3600 seconds." + } + }, + { + "name": "contentType", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "the `Content-Type` header value. Should be specified if using a `fileBody` that is neither `Blob` nor `File` nor `FormData`, otherwise will default to `text/plain;charset=UTF-8`." + } + }, + { + "name": "duplex", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The duplex option is a string parameter that enables or disables duplex streaming, allowing for both reading and writing data in the same stream. It can be passed as an option to the fetch() method." + } + }, + { + "name": "headers", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Optionally add extra headers" + } + }, + { + "name": "metadata", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "The metadata option is an object that allows you to store additional information about the file. This information can be used to filter and search for files. The metadata object can contain any key-value pairs you want to store." + } + }, + { + "name": "upsert", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "When upsert is set to true, the file is overwritten if it exists. When set to false, an error is thrown if the object already exists. Defaults to false." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "HTTP headers (cacheControl, contentType, etc.).\n**Note:** The `upsert` option has no effect here. To enable upsert behavior,\npass `{ upsert: true }` when calling `createSignedUploadUrl()` instead." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "fullPath", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "path", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Upload a file with a token generated from `createSignedUploadUrl`.", + "text": "- RLS policy permissions required:\n - `buckets` table permissions: none\n - `objects` table permissions: none\n- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works", + "examples": [ + { + "id": "upload-to-a-signed-url", + "name": "Upload to a signed URL", + "code": "```js\nconst { data, error } = await supabase\n .storage\n .from('avatars')\n .uploadToSignedUrl('folder/cat.jpg', 'token-from-createSignedUploadUrl', file)\n```", + "response": "```json\n{\n \"data\": {\n \"path\": \"folder/cat.jpg\",\n \"fullPath\": \"avatars/folder/cat.jpg\"\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.constructor": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.constructor", + "params": [ + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Base URL of the Storage Vectors REST API." + } + }, + { + "name": "options", + "type": { + "type": "object", + "name": "StorageVectorsClientOptions", + "properties": [ + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RequestInfo" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true, + "comment": { + "shortText": "Custom fetch implementation (optional)\nUseful for testing or custom request handling", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ] + } + }, + { + "name": "headers", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Custom headers to include in all requests", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ] + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "StorageVectorsClient" + } + }, + "comment": { + "shortText": "Creates a StorageVectorsClient that can manage buckets, indexes, and vectors.\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```typescript\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst bucket = supabase.storage.vectors.from('embeddings-prod')\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```typescript\nimport { StorageVectorsClient } from '@supabase/storage-js'\n\nconst client = new StorageVectorsClient(url, options)\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.createBucket": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.createBucket", + "params": [ + { + "name": "vectorBucketName", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Unique name for the vector bucket" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "ApiResponse", + "subTypes": [ + { + "type": "object", + "name": "SuccessResponse", + "properties": [ + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "undefined" + }, + "comment": { + "shortText": "Response data of type T" + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + }, + "comment": { + "shortText": "Null on success" + } + } + ] + }, + { + "type": "object", + "name": "ErrorResponse", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + }, + "comment": { + "shortText": "Null on error" + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + }, + "comment": { + "shortText": "StorageError with details (named StorageVectorsError for vector operations)" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a new vector bucket\nVector buckets are containers for vector indexes and their data\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "creating-a-vector-bucket", + "name": "Creating a vector bucket", + "code": "```typescript\nconst { data, error } = await supabase\n .storage\n .vectors\n .createBucket('embeddings-prod')\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.deleteBucket": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.deleteBucket", + "params": [ + { + "name": "vectorBucketName", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Name of the vector bucket to delete" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "ApiResponse", + "subTypes": [ + { + "type": "object", + "name": "SuccessResponse", + "properties": [ + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "undefined" + }, + "comment": { + "shortText": "Response data of type T" + } + }, + { + "name": "error", + "type": "[Circular]", + "comment": { + "shortText": "Null on success" + } + } + ] + }, + { + "type": "object", + "name": "ErrorResponse", + "properties": [ + { + "name": "data", + "type": "[Circular]", + "comment": { + "shortText": "Null on error" + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + }, + "comment": { + "shortText": "StorageError with details (named StorageVectorsError for vector operations)" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Deletes a vector bucket (bucket must be empty)\nAll indexes must be deleted before deleting the bucket\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "delete-a-vector-bucket", + "name": "Delete a vector bucket", + "code": "```typescript\nconst { data, error } = await supabase\n .storage\n .vectors\n .deleteBucket('embeddings-old')\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.from": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.from", + "params": [ + { + "name": "vectorBucketName", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Name of the vector bucket" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "VectorBucketScope" + } + }, + "comment": { + "shortText": "Access operations for a specific vector bucket\nReturns a scoped client for index and vector operations within the bucket\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "accessing-a-vector-bucket", + "name": "Accessing a vector bucket", + "code": "```typescript\nconst bucket = supabase.storage.vectors.from('embeddings-prod')\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.getBucket": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.getBucket", + "params": [ + { + "name": "vectorBucketName", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Name of the vector bucket" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "ApiResponse", + "subTypes": [ + { + "type": "object", + "name": "SuccessResponse", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "vectorBucket", + "type": { + "type": "object", + "name": "VectorBucket", + "properties": [ + { + "name": "creationTime", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "Unix timestamp of when the bucket was created" + } + }, + { + "name": "encryptionConfiguration", + "type": { + "type": "object", + "name": "EncryptionConfiguration", + "properties": [ + { + "name": "kmsKeyArn", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "ARN of the KMS key used for encryption" + } + }, + { + "name": "sseType", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Server-side encryption type (e.g., 'KMS')" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Optional encryption settings" + } + }, + { + "name": "vectorBucketName", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Unique name of the vector bucket" + } + } + ] + } + } + ] + }, + "comment": { + "shortText": "Response data of type T" + } + }, + { + "name": "error", + "type": "[Circular]", + "comment": { + "shortText": "Null on success" + } + } + ] + }, + { + "type": "object", + "name": "ErrorResponse", + "properties": [ + { + "name": "data", + "type": "[Circular]", + "comment": { + "shortText": "Null on error" + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + }, + "comment": { + "shortText": "StorageError with details (named StorageVectorsError for vector operations)" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Retrieves metadata for a specific vector bucket\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "get-bucket-metadata", + "name": "Get bucket metadata", + "code": "```typescript\nconst { data, error } = await supabase\n .storage\n .vectors\n .getBucket('embeddings-prod')\n\nconsole.log('Bucket created:', data?.vectorBucket.creationTime)\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.listBuckets": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.listBuckets", + "params": [ + { + "name": "options", + "type": { + "type": "object", + "name": "ListVectorBucketsOptions", + "properties": [ + { + "name": "maxResults", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "Maximum number of results to return (default: 100)" + } + }, + { + "name": "nextToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Token for pagination from previous response" + } + }, + { + "name": "prefix", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Filter buckets by name prefix" + } + } + ] + }, + "comment": { + "shortText": "Optional filters (prefix, maxResults, nextToken)" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "ApiResponse", + "subTypes": [ + { + "type": "object", + "name": "SuccessResponse", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "name": "ListVectorBucketsResponse", + "properties": [ + { + "name": "nextToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Token for fetching next page (if more results exist)" + } + }, + { + "name": "vectorBuckets", + "type": { + "type": "array", + "elemType": { + "type": "object", + "properties": [ + { + "name": "vectorBucketName", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + "comment": { + "shortText": "Array of bucket names" + } + } + ] + }, + "comment": { + "shortText": "Response data of type T" + } + }, + { + "name": "error", + "type": "[Circular]", + "comment": { + "shortText": "Null on success" + } + } + ] + }, + { + "type": "object", + "name": "ErrorResponse", + "properties": [ + { + "name": "data", + "type": "[Circular]", + "comment": { + "shortText": "Null on error" + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + }, + "comment": { + "shortText": "StorageError with details (named StorageVectorsError for vector operations)" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists all vector buckets with optional filtering and pagination\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "list-vector-buckets", + "name": "List vector buckets", + "code": "```typescript\nconst { data, error } = await supabase\n .storage\n .vectors\n .listBuckets({ prefix: 'embeddings-' })\n\ndata?.vectorBuckets.forEach(bucket => {\n console.log(bucket.vectorBucketName)\n})\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.setHeader": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.setHeader", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Header name" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Header value" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set an HTTP header for the request.\nCreates a shallow copy of headers to avoid mutating shared state.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.throwOnError": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.StorageVectorsClient.throwOnError", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Enable throwing errors instead of returning them.\nWhen enabled, errors are thrown instead of returned in { data, error } format.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.constructor": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.constructor", + "params": [ + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "headers", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + } + }, + { + "name": "vectorBucketName", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RequestInfo" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "VectorBucketScope" + } + }, + "comment": { + "shortText": "Creates a helper that automatically scopes all index operations to the provided bucket.\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "creating-a-vector-bucket-scope", + "name": "Creating a vector bucket scope", + "code": "```typescript\nconst bucket = supabase.storage.vectors.from('embeddings-prod')\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.createIndex": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.createIndex", + "params": [ + { + "name": "options", + "type": { + "type": "nameOnly", + "name": "Omit" + }, + "comment": { + "shortText": "Index configuration (vectorBucketName is automatically set)" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "ApiResponse", + "subTypes": [ + { + "type": "object", + "name": "SuccessResponse", + "properties": [ + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "undefined" + }, + "comment": { + "shortText": "Response data of type T" + } + }, + { + "name": "error", + "type": "[Circular]", + "comment": { + "shortText": "Null on success" + } + } + ] + }, + { + "type": "object", + "name": "ErrorResponse", + "properties": [ + { + "name": "data", + "type": "[Circular]", + "comment": { + "shortText": "Null on error" + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + }, + "comment": { + "shortText": "StorageError with details (named StorageVectorsError for vector operations)" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a new vector index in this bucket\nConvenience method that automatically includes the bucket name\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "creating-a-vector-index", + "name": "Creating a vector index", + "code": "```typescript\nconst bucket = supabase.storage.vectors.from('embeddings-prod')\nawait bucket.createIndex({\n indexName: 'documents-openai',\n dataType: 'float32',\n dimension: 1536,\n distanceMetric: 'cosine',\n metadataConfiguration: {\n nonFilterableMetadataKeys: ['raw_text']\n }\n})\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.deleteIndex": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.deleteIndex", + "params": [ + { + "name": "indexName", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Name of the index to delete" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "ApiResponse", + "subTypes": [ + { + "type": "object", + "name": "SuccessResponse", + "properties": [ + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "undefined" + }, + "comment": { + "shortText": "Response data of type T" + } + }, + { + "name": "error", + "type": "[Circular]", + "comment": { + "shortText": "Null on success" + } + } + ] + }, + { + "type": "object", + "name": "ErrorResponse", + "properties": [ + { + "name": "data", + "type": "[Circular]", + "comment": { + "shortText": "Null on error" + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + }, + "comment": { + "shortText": "StorageError with details (named StorageVectorsError for vector operations)" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Deletes an index from this bucket\nConvenience method that automatically includes the bucket name\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "delete-an-index", + "name": "Delete an index", + "code": "```typescript\nconst bucket = supabase.storage.vectors.from('embeddings-prod')\nawait bucket.deleteIndex('old-index')\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.getIndex": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.getIndex", + "params": [ + { + "name": "indexName", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Name of the index to retrieve" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "ApiResponse", + "subTypes": [ + { + "type": "object", + "name": "SuccessResponse", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "index", + "type": { + "type": "object", + "name": "VectorIndex", + "properties": [ + { + "name": "creationTime", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "Unix timestamp of when the index was created" + } + }, + { + "name": "dataType", + "type": { + "type": "union", + "name": "VectorDataType", + "subTypes": [ + { + "type": "literal", + "value": "float32" + }, + null + ] + }, + "comment": { + "shortText": "Data type of vector components (currently only 'float32')" + } + }, + { + "name": "dimension", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "Dimensionality of vectors (e.g., 384, 768, 1536)" + } + }, + { + "name": "distanceMetric", + "type": { + "type": "union", + "name": "DistanceMetric", + "subTypes": [ + { + "type": "literal", + "value": "cosine" + }, + { + "type": "literal", + "value": "euclidean" + }, + { + "type": "literal", + "value": "dotproduct" + }, + null + ] + }, + "comment": { + "shortText": "Similarity metric used for queries" + } + }, + { + "name": "indexName", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Unique name of the index within the bucket" + } + }, + { + "name": "metadataConfiguration", + "type": { + "type": "object", + "name": "MetadataConfiguration", + "properties": [ + { + "name": "nonFilterableMetadataKeys", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Array of metadata keys that cannot be used in filters" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Configuration for metadata filtering" + } + }, + { + "name": "vectorBucketName", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Name of the parent vector bucket" + } + } + ] + } + } + ] + }, + "comment": { + "shortText": "Response data of type T" + } + }, + { + "name": "error", + "type": "[Circular]", + "comment": { + "shortText": "Null on success" + } + } + ] + }, + { + "type": "object", + "name": "ErrorResponse", + "properties": [ + { + "name": "data", + "type": "[Circular]", + "comment": { + "shortText": "Null on error" + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + }, + "comment": { + "shortText": "StorageError with details (named StorageVectorsError for vector operations)" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Retrieves metadata for a specific index in this bucket\nConvenience method that automatically includes the bucket name\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "get-index-metadata", + "name": "Get index metadata", + "code": "```typescript\nconst bucket = supabase.storage.vectors.from('embeddings-prod')\nconst { data } = await bucket.getIndex('documents-openai')\nconsole.log('Dimension:', data?.index.dimension)\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope", + "params": [ + { + "name": "indexName", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Name of the index" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "VectorIndexScope" + } + }, + "comment": { + "shortText": "Access operations for a specific index within this bucket\nReturns a scoped client for vector data operations\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "accessing-an-index", + "name": "Accessing an index", + "code": "```typescript\nconst index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\n\n// Insert vectors\nawait index.putVectors({\n vectors: [\n { key: 'doc-1', data: { float32: [...] }, metadata: { title: 'Intro' } }\n ]\n})\n\n// Query similar vectors\nconst { data } = await index.queryVectors({\n queryVector: { float32: [...] },\n topK: 5\n})\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.listIndexes": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.listIndexes", + "params": [ + { + "name": "options", + "type": { + "type": "nameOnly", + "name": "Omit" + }, + "comment": { + "shortText": "Listing options (vectorBucketName is automatically set)" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "ApiResponse", + "subTypes": [ + { + "type": "object", + "name": "SuccessResponse", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "name": "ListIndexesResponse", + "properties": [ + { + "name": "indexes", + "type": { + "type": "array", + "elemType": { + "type": "object", + "properties": [ + { + "name": "indexName", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + "comment": { + "shortText": "Array of index names" + } + }, + { + "name": "nextToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Token for fetching next page (if more results exist)" + } + } + ] + }, + "comment": { + "shortText": "Response data of type T" + } + }, + { + "name": "error", + "type": "[Circular]", + "comment": { + "shortText": "Null on success" + } + } + ] + }, + { + "type": "object", + "name": "ErrorResponse", + "properties": [ + { + "name": "data", + "type": "[Circular]", + "comment": { + "shortText": "Null on error" + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + }, + "comment": { + "shortText": "StorageError with details (named StorageVectorsError for vector operations)" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists indexes in this bucket\nConvenience method that automatically includes the bucket name\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "list-indexes", + "name": "List indexes", + "code": "```typescript\nconst bucket = supabase.storage.vectors.from('embeddings-prod')\nconst { data } = await bucket.listIndexes({ prefix: 'documents-' })\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.setHeader": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.setHeader", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Header name" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Header value" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set an HTTP header for the request.\nCreates a shallow copy of headers to avoid mutating shared state.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.throwOnError": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.VectorBucketScope.throwOnError", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Enable throwing errors instead of returning them.\nWhen enabled, errors are thrown instead of returned in { data, error } format.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.constructor": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.constructor", + "params": [ + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "headers", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + } + }, + { + "name": "vectorBucketName", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "indexName", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RequestInfo" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "VectorIndexScope" + } + }, + "comment": { + "shortText": "Creates a helper that automatically scopes all vector operations to the provided bucket/index names.\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "creating-a-vector-index-scope", + "name": "Creating a vector index scope", + "code": "```typescript\nconst index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.deleteVectors": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.deleteVectors", + "params": [ + { + "name": "options", + "type": { + "type": "nameOnly", + "name": "Omit" + }, + "comment": { + "shortText": "Deletion options (bucket and index names automatically set)" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "ApiResponse", + "subTypes": [ + { + "type": "object", + "name": "SuccessResponse", + "properties": [ + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "undefined" + }, + "comment": { + "shortText": "Response data of type T" + } + }, + { + "name": "error", + "type": "[Circular]", + "comment": { + "shortText": "Null on success" + } + } + ] + }, + { + "type": "object", + "name": "ErrorResponse", + "properties": [ + { + "name": "data", + "type": "[Circular]", + "comment": { + "shortText": "Null on error" + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + }, + "comment": { + "shortText": "StorageError with details (named StorageVectorsError for vector operations)" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Deletes vectors by keys from this index\nConvenience method that automatically includes bucket and index names\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "delete-vectors-by-keys", + "name": "Delete vectors by keys", + "code": "```typescript\nconst index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\nawait index.deleteVectors({\n keys: ['doc-1', 'doc-2', 'doc-3']\n})\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.getVectors": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.getVectors", + "params": [ + { + "name": "options", + "type": { + "type": "nameOnly", + "name": "Omit" + }, + "comment": { + "shortText": "Vector retrieval options (bucket and index names automatically set)" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "ApiResponse", + "subTypes": [ + { + "type": "object", + "name": "SuccessResponse", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "name": "GetVectorsResponse", + "properties": [ + { + "name": "vectors", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "VectorMatch", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "name": "VectorData", + "properties": [ + { + "name": "float32", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "number" + } + }, + "comment": { + "shortText": "Array of 32-bit floating point numbers" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Vector embedding data (if requested)" + } + }, + { + "name": "distance", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "Similarity distance from query vector (if requested)" + } + }, + { + "name": "key", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Unique identifier for the vector" + } + }, + { + "name": "metadata", + "type": { + "type": "record", + "name": "VectorMetadata", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + "isOptional": true, + "comment": { + "shortText": "Arbitrary metadata (if requested)" + } + } + ] + } + }, + "comment": { + "shortText": "Array of retrieved vector objects" + } + } + ] + }, + "comment": { + "shortText": "Response data of type T" + } + }, + { + "name": "error", + "type": "[Circular]", + "comment": { + "shortText": "Null on success" + } + } + ] + }, + { + "type": "object", + "name": "ErrorResponse", + "properties": [ + { + "name": "data", + "type": "[Circular]", + "comment": { + "shortText": "Null on error" + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + }, + "comment": { + "shortText": "StorageError with details (named StorageVectorsError for vector operations)" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Retrieves vectors by keys from this index\nConvenience method that automatically includes bucket and index names\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "get-vectors-by-keys", + "name": "Get vectors by keys", + "code": "```typescript\nconst index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\nconst { data } = await index.getVectors({\n keys: ['doc-1', 'doc-2'],\n returnMetadata: true\n})\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.listVectors": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.listVectors", + "params": [ + { + "name": "options", + "type": { + "type": "nameOnly", + "name": "Omit" + }, + "comment": { + "shortText": "Listing options (bucket and index names automatically set)" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "ApiResponse", + "subTypes": [ + { + "type": "object", + "name": "SuccessResponse", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "name": "ListVectorsResponse", + "properties": [ + { + "name": "nextToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Token for fetching next page (if more results exist)" + } + }, + { + "name": "vectors", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "VectorMatch", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "name": "VectorData", + "properties": [ + { + "name": "float32", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "comment": { + "shortText": "Array of 32-bit floating point numbers" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Vector embedding data (if requested)" + } + }, + { + "name": "distance", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Similarity distance from query vector (if requested)" + } + }, + { + "name": "key", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier for the vector" + } + }, + { + "name": "metadata", + "type": { + "type": "record", + "name": "VectorMetadata", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Arbitrary metadata (if requested)" + } + } + ] + } + }, + "comment": { + "shortText": "Array of vector objects" + } + } + ] + }, + "comment": { + "shortText": "Response data of type T" + } + }, + { + "name": "error", + "type": "[Circular]", + "comment": { + "shortText": "Null on success" + } + } + ] + }, + { + "type": "object", + "name": "ErrorResponse", + "properties": [ + { + "name": "data", + "type": "[Circular]", + "comment": { + "shortText": "Null on error" + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + }, + "comment": { + "shortText": "StorageError with details (named StorageVectorsError for vector operations)" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists vectors in this index with pagination\nConvenience method that automatically includes bucket and index names\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "list-vectors-with-pagination", + "name": "List vectors with pagination", + "code": "```typescript\nconst index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\nconst { data } = await index.listVectors({\n maxResults: 500,\n returnMetadata: true\n})\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.putVectors": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.putVectors", + "params": [ + { + "name": "options", + "type": { + "type": "nameOnly", + "name": "Omit" + }, + "comment": { + "shortText": "Vector insertion options (bucket and index names automatically set)" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "ApiResponse", + "subTypes": [ + { + "type": "object", + "name": "SuccessResponse", + "properties": [ + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "undefined" + }, + "comment": { + "shortText": "Response data of type T" + } + }, + { + "name": "error", + "type": "[Circular]", + "comment": { + "shortText": "Null on success" + } + } + ] + }, + { + "type": "object", + "name": "ErrorResponse", + "properties": [ + { + "name": "data", + "type": "[Circular]", + "comment": { + "shortText": "Null on error" + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + }, + "comment": { + "shortText": "StorageError with details (named StorageVectorsError for vector operations)" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Inserts or updates vectors in this index\nConvenience method that automatically includes bucket and index names\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "insert-vectors-into-an-index", + "name": "Insert vectors into an index", + "code": "```typescript\nconst index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\nawait index.putVectors({\n vectors: [\n {\n key: 'doc-1',\n data: { float32: [0.1, 0.2, ...] },\n metadata: { title: 'Introduction', page: 1 }\n }\n ]\n})\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.queryVectors": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.queryVectors", + "params": [ + { + "name": "options", + "type": { + "type": "nameOnly", + "name": "Omit" + }, + "comment": { + "shortText": "Query options (bucket and index names automatically set)" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "ApiResponse", + "subTypes": [ + { + "type": "object", + "name": "SuccessResponse", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "name": "QueryVectorsResponse", + "properties": [ + { + "name": "distanceMetric", + "type": { + "type": "union", + "name": "DistanceMetric", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + }, + "isOptional": true, + "comment": { + "shortText": "The distance metric used for the similarity search" + } + }, + { + "name": "vectors", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "VectorMatch", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "name": "VectorData", + "properties": [ + { + "name": "float32", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "comment": { + "shortText": "Array of 32-bit floating point numbers" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Vector embedding data (if requested)" + } + }, + { + "name": "distance", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Similarity distance from query vector (if requested)" + } + }, + { + "name": "key", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier for the vector" + } + }, + { + "name": "metadata", + "type": { + "type": "record", + "name": "VectorMetadata", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Arbitrary metadata (if requested)" + } + } + ] + } + }, + "comment": { + "shortText": "Array of similar vectors ordered by distance" + } + } + ] + }, + "comment": { + "shortText": "Response data of type T" + } + }, + { + "name": "error", + "type": "[Circular]", + "comment": { + "shortText": "Null on success" + } + } + ] + }, + { + "type": "object", + "name": "ErrorResponse", + "properties": [ + { + "name": "data", + "type": "[Circular]", + "comment": { + "shortText": "Null on error" + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + }, + "comment": { + "shortText": "StorageError with details (named StorageVectorsError for vector operations)" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Queries for similar vectors in this index\nConvenience method that automatically includes bucket and index names\n\n**Public alpha:** This API is part of a public alpha release and may not be available to your account type.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ], + "examples": [ + { + "id": "query-similar-vectors", + "name": "Query similar vectors", + "code": "```typescript\nconst index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\nconst { data } = await index.queryVectors({\n queryVector: { float32: [0.1, 0.2, ...] },\n topK: 5,\n filter: { category: 'technical' },\n returnDistance: true,\n returnMetadata: true\n})\n```" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.setHeader": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.setHeader", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Header name" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Header value" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set an HTTP header for the request.\nCreates a shallow copy of headers to avoid mutating shared state.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ] + } + }, + "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.throwOnError": { + "name": "@supabase/storage-js.packages/StorageVectorsClient.VectorIndexScope.throwOnError", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Enable throwing errors instead of returning them.\nWhen enabled, errors are thrown instead of returned in { data, error } format.", + "tags": [ + { + "tag": "alpha", + "text": "" + } + ] + } + }, + "@supabase/storage-js.packages/StreamDownloadBuilder.default.constructor": { + "name": "@supabase/storage-js.packages/StreamDownloadBuilder.default.constructor", + "params": [ + { + "name": "downloadFn", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + } + } + }, + { + "name": "shouldThrowOnError", + "type": { + "type": "intrinsic", + "name": "boolean" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "default" + } + } + }, + "@supabase/storage-js.packages/StreamDownloadBuilder.default.catch": { + "name": "@supabase/storage-js.packages/StreamDownloadBuilder.default.catch", + "params": [ + { + "name": "onrejected", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "reason", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is rejected." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "union", + "name": "DownloadResult", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "nameOnly", + "name": "ReadableStream" + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + }, + { + "type": "nameOnly", + "name": "TResult" + } + ] + } + } + }, + "comment": { + "shortText": "Attaches a callback for only the rejection of the Promise." + } + }, + "@supabase/storage-js.packages/StreamDownloadBuilder.default.finally": { + "name": "@supabase/storage-js.packages/StreamDownloadBuilder.default.finally", + "params": [ + { + "name": "onfinally", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is settled (fulfilled or rejected)." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "DownloadResult", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "nameOnly", + "name": "ReadableStream" + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The\nresolved value cannot be modified from the callback." + } + }, + "@supabase/storage-js.packages/StreamDownloadBuilder.default.then": { + "name": "@supabase/storage-js.packages/StreamDownloadBuilder.default.then", + "params": [ + { + "name": "onfulfilled", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "value", + "type": { + "type": "union", + "name": "DownloadResult", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "nameOnly", + "name": "ReadableStream" + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "StorageError" + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult1" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is resolved." + } + }, + { + "name": "onrejected", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "reason", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult2" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is rejected." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult1" + }, + { + "type": "nameOnly", + "name": "TResult2" + } + ] + } + } + }, + "comment": { + "shortText": "Attaches callbacks for the resolution and/or rejection of the Promise." + } + }, + "@supabase/supabase-js.AuthApiError.constructor": { + "name": "@supabase/supabase-js.AuthApiError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthApiError" + } + } + }, + "@supabase/supabase-js.AuthApiError.toJSON": { + "name": "@supabase/supabase-js.AuthApiError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "nameOnly", + "name": "ErrorCode" + }, + null + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/supabase-js.AuthError.constructor": { + "name": "@supabase/supabase-js.AuthError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + }, + "@supabase/supabase-js.AuthError.toJSON": { + "name": "@supabase/supabase-js.AuthError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "nameOnly", + "name": "ErrorCode" + }, + null + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/supabase-js.AuthImplicitGrantRedirectError.constructor": { + "name": "@supabase/supabase-js.AuthImplicitGrantRedirectError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "details", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthImplicitGrantRedirectError" + } + } + }, + "@supabase/supabase-js.AuthImplicitGrantRedirectError.toJSON": { + "name": "@supabase/supabase-js.AuthImplicitGrantRedirectError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "nameOnly", + "name": "ErrorCode" + }, + null + ] + } + }, + { + "name": "details", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/supabase-js.AuthInvalidCredentialsError.constructor": { + "name": "@supabase/supabase-js.AuthInvalidCredentialsError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthInvalidCredentialsError" + } + } + }, + "@supabase/supabase-js.AuthInvalidCredentialsError.toJSON": { + "name": "@supabase/supabase-js.AuthInvalidCredentialsError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "nameOnly", + "name": "ErrorCode" + }, + null + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/supabase-js.AuthInvalidJwtError.constructor": { + "name": "@supabase/supabase-js.AuthInvalidJwtError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthInvalidJwtError" + } + } + }, + "@supabase/supabase-js.AuthInvalidJwtError.toJSON": { + "name": "@supabase/supabase-js.AuthInvalidJwtError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "nameOnly", + "name": "ErrorCode" + }, + null + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/supabase-js.AuthInvalidTokenResponseError.constructor": { + "name": "@supabase/supabase-js.AuthInvalidTokenResponseError.constructor", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthInvalidTokenResponseError" + } + } + }, + "@supabase/supabase-js.AuthInvalidTokenResponseError.toJSON": { + "name": "@supabase/supabase-js.AuthInvalidTokenResponseError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "nameOnly", + "name": "ErrorCode" + }, + null + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/supabase-js.AuthPKCECodeVerifierMissingError.constructor": { + "name": "@supabase/supabase-js.AuthPKCECodeVerifierMissingError.constructor", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthPKCECodeVerifierMissingError" + } + } + }, + "@supabase/supabase-js.AuthPKCECodeVerifierMissingError.toJSON": { + "name": "@supabase/supabase-js.AuthPKCECodeVerifierMissingError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "nameOnly", + "name": "ErrorCode" + }, + null + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/supabase-js.AuthPKCEGrantCodeExchangeError.constructor": { + "name": "@supabase/supabase-js.AuthPKCEGrantCodeExchangeError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "details", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthPKCEGrantCodeExchangeError" + } + } + }, + "@supabase/supabase-js.AuthPKCEGrantCodeExchangeError.toJSON": { + "name": "@supabase/supabase-js.AuthPKCEGrantCodeExchangeError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "nameOnly", + "name": "ErrorCode" + }, + null + ] + } + }, + { + "name": "details", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/supabase-js.AuthRefreshDiscardedError.constructor": { + "name": "@supabase/supabase-js.AuthRefreshDiscardedError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthRefreshDiscardedError" + } + } + }, + "@supabase/supabase-js.AuthRefreshDiscardedError.toJSON": { + "name": "@supabase/supabase-js.AuthRefreshDiscardedError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "nameOnly", + "name": "ErrorCode" + }, + null + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/supabase-js.AuthRetryableFetchError.constructor": { + "name": "@supabase/supabase-js.AuthRetryableFetchError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthRetryableFetchError" + } + } + }, + "@supabase/supabase-js.AuthRetryableFetchError.toJSON": { + "name": "@supabase/supabase-js.AuthRetryableFetchError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "nameOnly", + "name": "ErrorCode" + }, + null + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/supabase-js.AuthSessionMissingError.constructor": { + "name": "@supabase/supabase-js.AuthSessionMissingError.constructor", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthSessionMissingError" + } + } + }, + "@supabase/supabase-js.AuthSessionMissingError.toJSON": { + "name": "@supabase/supabase-js.AuthSessionMissingError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "nameOnly", + "name": "ErrorCode" + }, + null + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/supabase-js.AuthUnknownError.constructor": { + "name": "@supabase/supabase-js.AuthUnknownError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "originalError", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthUnknownError" + } + } + }, + "@supabase/supabase-js.AuthUnknownError.toJSON": { + "name": "@supabase/supabase-js.AuthUnknownError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "nameOnly", + "name": "ErrorCode" + }, + null + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/supabase-js.AuthWeakPasswordError.constructor": { + "name": "@supabase/supabase-js.AuthWeakPasswordError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "reasons", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "length" + }, + { + "type": "literal", + "value": "characters" + }, + { + "type": "literal", + "value": "pwned" + } + ] + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "AuthWeakPasswordError" + } + } + }, + "@supabase/supabase-js.AuthWeakPasswordError.toJSON": { + "name": "@supabase/supabase-js.AuthWeakPasswordError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "nameOnly", + "name": "ErrorCode" + }, + null + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "reasons", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "length" + }, + { + "type": "literal", + "value": "characters" + }, + { + "type": "literal", + "value": "pwned" + } + ] + } + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/supabase-js.CustomAuthError.constructor": { + "name": "@supabase/supabase-js.CustomAuthError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "CustomAuthError" + } + } + }, + "@supabase/supabase-js.CustomAuthError.toJSON": { + "name": "@supabase/supabase-js.CustomAuthError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "nameOnly", + "name": "ErrorCode" + }, + null + ] + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + } + ] + } + } + }, + "@supabase/supabase-js.FunctionsError.constructor": { + "name": "@supabase/supabase-js.FunctionsError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "context", + "type": { + "type": "intrinsic", + "name": "any" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "FunctionsError" + } + } + }, + "@supabase/supabase-js.FunctionsError.toJSON": { + "name": "@supabase/supabase-js.FunctionsError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "context", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + }, + "@supabase/supabase-js.FunctionsFetchError.constructor": { + "name": "@supabase/supabase-js.FunctionsFetchError.constructor", + "params": [ + { + "name": "context", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "FunctionsFetchError" + } + } + }, + "@supabase/supabase-js.FunctionsFetchError.toJSON": { + "name": "@supabase/supabase-js.FunctionsFetchError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "context", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + }, + "@supabase/supabase-js.FunctionsHttpError.constructor": { + "name": "@supabase/supabase-js.FunctionsHttpError.constructor", + "params": [ + { + "name": "context", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "FunctionsHttpError" + } + } + }, + "@supabase/supabase-js.FunctionsHttpError.toJSON": { + "name": "@supabase/supabase-js.FunctionsHttpError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "context", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + }, + "@supabase/supabase-js.FunctionsRelayError.constructor": { + "name": "@supabase/supabase-js.FunctionsRelayError.constructor", + "params": [ + { + "name": "context", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "FunctionsRelayError" + } + } + }, + "@supabase/supabase-js.FunctionsRelayError.toJSON": { + "name": "@supabase/supabase-js.FunctionsRelayError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "context", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + }, + "@supabase/supabase-js.GoTrueAdminApi.constructor": { + "name": "@supabase/supabase-js.GoTrueAdminApi.constructor", + "params": [ + { + "type": { + "type": "object", + "properties": [ + { + "name": "experimental", + "type": { + "name": "ExperimentalFeatureFlags", + "type": "object", + "properties": [ + { + "name": "passkey", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Enables passkey support:\n - `auth.signInWithPasskey()`, `auth.registerPasskey()`\n - `auth.passkey.*`\n - `auth.admin.passkey.*`\n\nDefaults to `false`. Calling any passkey method while this flag is\ndisabled throws a descriptive error at call time." + } + } + ] + }, + "isOptional": true + }, + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RequestInfo" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true + }, + { + "name": "headers", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true + }, + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "GoTrueAdminApi" + } + }, + "comment": { + "shortText": "Creates an admin API client that can be used to manage users and OAuth clients.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-secret-key')\nconst { data, error } = await supabase.auth.admin.listUsers()\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport { GoTrueAdminApi } from '@supabase/auth-js'\n\nconst admin = new GoTrueAdminApi({\n url: 'https://xyzcompany.supabase.co/auth/v1',\n headers: { Authorization: `Bearer ${process.env.SUPABASE_SECRET_KEY}` },\n})\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueAdminApi.createUser": { + "name": "@supabase/supabase-js.GoTrueAdminApi.createUser", + "params": [ + { + "name": "attributes", + "type": { + "type": "object", + "name": "AdminUserAttributes", + "properties": [ + { + "name": "app_metadata", + "type": { + "type": "intrinsic", + "name": "object" + }, + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's application specific metadata. This maps to the `auth.users.app_metadata` column.\n\nOnly a service role can modify.\n\nThe `app_metadata` should be a JSON object that includes app-specific info, such as identity providers, roles, and other\naccess control information." + } + }, + { + "name": "ban_duration", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Determines how long a user is banned for.\n\nThe format for the ban duration follows a strict sequence of decimal numbers with a unit suffix.\nValid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\".\n\nFor example, some possible durations include: '300ms', '2h45m'.\n\nSetting the ban duration to 'none' lifts the ban on the user." + } + }, + { + "name": "current_password", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The user's current password\n\nThis is only ever present when the user is resetting\ntheir password and GOTRUE_SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD is true." + } + }, + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The user's email." + } + }, + { + "name": "email_confirm", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Sets the user's email as confirmed when true, or unconfirmed when false.\n\nOnly a service role can modify." + } + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The `id` for the user.\n\nAllows you to overwrite the default `id` set for the user." + } + }, + { + "name": "nonce", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The nonce sent for reauthentication if the user's password is to be updated.\n\nCall reauthenticate() to obtain the nonce first." + } + }, + { + "name": "password", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The user's password." + } + }, + { + "name": "password_hash", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The `password_hash` for the user's password.\n\nAllows you to specify a password hash for the user. This is useful for migrating a user's password hash from another service.\n\nSupports bcrypt, scrypt (firebase), and argon2 password hashes." + } + }, + { + "name": "phone", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The user's phone." + } + }, + { + "name": "phone_confirm", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Sets the user's phone as confirmed when true, or unconfirmed when false.\n\nOnly a service role can modify." + } + }, + { + "name": "role", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The `role` claim set in the user's access token JWT.\n\nWhen a user signs up, this role is set to `authenticated` by default. You should only modify the `role` if you need to provision several levels of admin access that have different permissions on individual columns in your database.\n\nSetting this role to `service_role` is not recommended as it grants the user admin privileges." + } + }, + { + "name": "user_metadata", + "type": { + "type": "intrinsic", + "name": "object" + }, + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.\n\n\nThe `user_metadata` should be a JSON object that includes user-specific info, such as their first and last name.\n\nNote: When using the GoTrueAdminApi and wanting to modify a user's metadata,\nthis attribute is used instead of UserAttributes data." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "UserResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "banned_until", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "confirmed_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "deleted_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "webauthn" + }, + { + "type": "literal", + "value": "totp" + }, + { + "type": "literal", + "value": "phone" + } + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "webauthn" + }, + { + "type": "literal", + "value": "totp" + }, + { + "type": "literal", + "value": "phone" + } + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "last_sign_in_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "provider", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "updated_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "user_id", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "is_anonymous", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "is_sso_user", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "new_email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "new_phone", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "phone", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "role", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "updated_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "literal", + "value": null + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a new user.\nThis function should only be called on a server. Never expose your `service_role` key in the browser.", + "text": "- To confirm the user's email address or phone number, set `email_confirm` or `phone_confirm` to true. Both arguments default to false.\n- `createUser()` will not send a confirmation email to the user. You can use [`inviteUserByEmail()`](/docs/reference/javascript/auth-admin-inviteuserbyemail) if you want to send them an email invite instead.\n- If you are sure that the created user's email or phone number is legitimate and verified, you can set the `email_confirm` or `phone_confirm` param to `true`.", + "examples": [ + { + "id": "with-custom-user-metadata", + "name": "With custom user metadata", + "code": "```js\nconst { data, error } = await supabase.auth.admin.createUser({\n email: 'user@email.com',\n password: 'password',\n user_metadata: { name: 'Yoda' }\n})\n```", + "response": "```json\n{\n data: {\n user: {\n id: '1',\n aud: 'authenticated',\n role: 'authenticated',\n email: 'example@email.com',\n email_confirmed_at: '2024-01-01T00:00:00Z',\n phone: '',\n confirmation_sent_at: '2024-01-01T00:00:00Z',\n confirmed_at: '2024-01-01T00:00:00Z',\n last_sign_in_at: '2024-01-01T00:00:00Z',\n app_metadata: {},\n user_metadata: {},\n identities: [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"1\",\n \"user_id\": \"1\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": true,\n \"phone_verified\": false,\n \"sub\": \"1\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"email@example.com\"\n },\n ],\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n is_anonymous: false,\n }\n }\n error: null\n}\n```" + }, + { + "id": "auto-confirm-the-user-s-email", + "name": "Auto-confirm the user's email", + "code": "```js\nconst { data, error } = await supabase.auth.admin.createUser({\n email: 'user@email.com',\n email_confirm: true\n})\n```" + }, + { + "id": "auto-confirm-the-user-s-phone-number", + "name": "Auto-confirm the user's phone number", + "code": "```js\nconst { data, error } = await supabase.auth.admin.createUser({\n phone: '1234567890',\n phone_confirm: true\n})\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueAdminApi.deleteUser": { + "name": "@supabase/supabase-js.GoTrueAdminApi.deleteUser", + "params": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user id you want to remove." + } + }, + { + "name": "shouldSoftDelete", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If true, then the user will be soft-deleted from the auth schema. Soft deletion allows user identification from the hashed user ID but is not reversible.\nDefaults to false for backward compatibility.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "UserResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Delete a user. Requires a `service_role` key.", + "text": "- The `deleteUser()` method requires the user's ID, which maps to the `auth.users.id` column.", + "examples": [ + { + "id": "removes-a-user", + "name": "Removes a user", + "code": "```js\nconst { data, error } = await supabase.auth.admin.deleteUser(\n '715ed5db-f090-4b8c-a067-640ecee36aa0'\n)\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {}\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueAdminApi.generateLink": { + "name": "@supabase/supabase-js.GoTrueAdminApi.generateLink", + "params": [ + { + "name": "params", + "type": { + "type": "union", + "name": "GenerateLinkParams", + "subTypes": [ + { + "name": "GenerateSignupLinkParams", + "type": "object", + "properties": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "isOptional": true + }, + { + "name": "password", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "signup" + } + } + ] + }, + { + "name": "GenerateInviteOrMagiclinkParams", + "type": "object", + "properties": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's email" + } + }, + { + "name": "options", + "isOptional": true + }, + { + "name": "type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "invite" + }, + { + "type": "literal", + "value": "magiclink" + } + ] + } + } + ] + }, + { + "name": "GenerateRecoveryLinkParams", + "type": "object", + "properties": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's email" + } + }, + { + "name": "options", + "isOptional": true + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "recovery" + } + } + ] + }, + { + "name": "GenerateEmailChangeLinkParams", + "type": "object", + "properties": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's email" + } + }, + { + "name": "newEmail", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's new email. Only required if type is 'email_change_current' or 'email_change_new'." + } + }, + { + "name": "options", + "isOptional": true + }, + { + "name": "type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "email_change_current" + }, + { + "type": "literal", + "value": "email_change_new" + } + ] + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "GenerateLinkResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "properties", + "type": { + "name": "GenerateLinkProperties", + "type": "object", + "properties": [ + { + "name": "action_link", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The email link to send to the user.\nThe action_link follows the following format: auth/v1/verify?type={verification_type}&token={hashed_token}&redirect_to={redirect_to}" + } + }, + { + "name": "email_otp", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The raw email OTP.\nYou should send this in the email if you want your users to verify using an OTP instead of the action link." + } + }, + { + "name": "hashed_token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The hashed token appended to the action link." + } + }, + { + "name": "redirect_to", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The URL appended to the action link." + } + }, + { + "name": "verification_type", + "type": { + "type": "union", + "name": "GenerateLinkType", + "subTypes": [ + { + "type": "literal", + "value": "signup" + }, + { + "type": "literal", + "value": "invite" + }, + { + "type": "literal", + "value": "magiclink" + }, + { + "type": "literal", + "value": "recovery" + }, + { + "type": "literal", + "value": "email_change_current" + }, + { + "type": "literal", + "value": "email_change_new" + } + ] + }, + "comment": { + "shortText": "The verification type that the email link is associated to." + } + } + ] + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "properties", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Generates email links and OTPs to be sent via a custom email provider.", + "text": "- The following types can be passed into `generateLink()`: `signup`, `magiclink`, `invite`, `recovery`, `email_change_current`, `email_change_new`, `phone_change`.\n- `generateLink()` only generates the email link for `email_change_email` if the **Secure email change** is enabled in your project's [email auth provider settings](/dashboard/project/_/auth/providers).\n- `generateLink()` handles the creation of the user for `signup`, `invite` and `magiclink`.", + "examples": [ + { + "id": "generate-a-signup-link", + "name": "Generate a signup link", + "code": "```js\nconst { data, error } = await supabase.auth.admin.generateLink({\n type: 'signup',\n email: 'email@example.com',\n password: 'secret'\n})\n```", + "response": "```json\n{\n \"data\": {\n \"properties\": {\n \"action_link\": \"\",\n \"email_otp\": \"999999\",\n \"hashed_token\": \"\",\n \"verification_type\": \"signup\"\n },\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"email@example.com\",\n \"phone\": \"\",\n \"confirmation_sent_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {},\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"email@example.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"email@example.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "generate-an-invite-link", + "name": "Generate an invite link", + "code": "```js\nconst { data, error } = await supabase.auth.admin.generateLink({\n type: 'invite',\n email: 'email@example.com'\n})\n```" + }, + { + "id": "generate-a-magic-link", + "name": "Generate a magic link", + "code": "```js\nconst { data, error } = await supabase.auth.admin.generateLink({\n type: 'magiclink',\n email: 'email@example.com'\n})\n```" + }, + { + "id": "generate-a-recovery-link", + "name": "Generate a recovery link", + "code": "```js\nconst { data, error } = await supabase.auth.admin.generateLink({\n type: 'recovery',\n email: 'email@example.com'\n})\n```" + }, + { + "id": "generate-links-to-change-current-email-address", + "name": "Generate links to change current email address", + "code": "```js\n// generate an email change link to be sent to the current email address\nconst { data, error } = await supabase.auth.admin.generateLink({\n type: 'email_change_current',\n email: 'current.email@example.com',\n newEmail: 'new.email@example.com'\n})\n\n// generate an email change link to be sent to the new email address\nconst { data, error } = await supabase.auth.admin.generateLink({\n type: 'email_change_new',\n email: 'current.email@example.com',\n newEmail: 'new.email@example.com'\n})\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueAdminApi.getUserById": { + "name": "@supabase/supabase-js.GoTrueAdminApi.getUserById", + "params": [ + { + "name": "uid", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's unique identifier\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "UserResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Get user by id.", + "text": "- Fetches the user object from the database based on the user's id.\n- The `getUserById()` method requires the user's id which maps to the `auth.users.id` column.", + "examples": [ + { + "id": "fetch-the-user-object-using-the-access-token-jwt", + "name": "Fetch the user object using the access_token jwt", + "code": "```js\nconst { data, error } = await supabase.auth.admin.getUserById(1)\n```", + "response": "```json\n{\n data: {\n user: {\n id: '1',\n aud: 'authenticated',\n role: 'authenticated',\n email: 'example@email.com',\n email_confirmed_at: '2024-01-01T00:00:00Z',\n phone: '',\n confirmation_sent_at: '2024-01-01T00:00:00Z',\n confirmed_at: '2024-01-01T00:00:00Z',\n last_sign_in_at: '2024-01-01T00:00:00Z',\n app_metadata: {},\n user_metadata: {},\n identities: [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"1\",\n \"user_id\": \"1\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": true,\n \"phone_verified\": false,\n \"sub\": \"1\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"email@example.com\"\n },\n ],\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n is_anonymous: false,\n }\n }\n error: null\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueAdminApi.inviteUserByEmail": { + "name": "@supabase/supabase-js.GoTrueAdminApi.inviteUserByEmail", + "params": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The email address of the user." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "object" + }, + "isOptional": true, + "comment": { + "shortText": "A custom data object to store additional metadata about the user. This maps to the `auth.users.user_metadata` column." + } + }, + { + "name": "redirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The URL which will be appended to the email link sent to the user's email address. Once clicked the user will end up on this URL." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Additional options to be included when inviting." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "UserResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Sends an invite link to an email address.", + "text": "- Sends an invite link to the user's email address.\n- The `inviteUserByEmail()` method is typically used by administrators to invite users to join the application.\n- Note that PKCE is not supported when using `inviteUserByEmail`. This is because the browser initiating the invite is often different from the browser accepting the invite which makes it difficult to provide the security guarantees required of the PKCE flow.", + "examples": [ + { + "id": "invite-a-user", + "name": "Invite a user", + "code": "```js\nconst { data, error } = await supabase.auth.admin.inviteUserByEmail('email@example.com')\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"invited_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmation_sent_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {},\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n }\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueAdminApi.listUsers": { + "name": "@supabase/supabase-js.GoTrueAdminApi.listUsers", + "params": [ + { + "name": "params", + "type": { + "name": "PageParams", + "type": "object", + "properties": [ + { + "name": "page", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "The page number" + } + }, + { + "name": "perPage", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "Number of items returned per page" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "An object which supports `page` and `perPage` as numbers, to alter the paginated results." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "users" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Get a list of users.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser.", + "text": "- Defaults to return 50 users per page.", + "examples": [ + { + "id": "get-a-page-of-users", + "name": "Get a page of users", + "code": "```js\nconst { data: { users }, error } = await supabase.auth.admin.listUsers()\n```" + }, + { + "id": "paginated-list-of-users", + "name": "Paginated list of users", + "code": "```js\nconst { data: { users }, error } = await supabase.auth.admin.listUsers({\n page: 1,\n perPage: 1000\n})\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueAdminApi.signOut": { + "name": "@supabase/supabase-js.GoTrueAdminApi.signOut", + "params": [ + { + "name": "jwt", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "A valid, logged-in JWT." + } + }, + { + "name": "scope", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "global" + }, + { + "type": "literal", + "value": "local" + }, + { + "type": "literal", + "value": "others" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The logout sope." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "nameOnly", + "name": "AuthError" + } + ] + } + } + ] + } + } + }, + "comment": { + "shortText": "Removes a logged-in session." + } + }, + "@supabase/supabase-js.GoTrueAdminApi.updateUserById": { + "name": "@supabase/supabase-js.GoTrueAdminApi.updateUserById", + "params": [ + { + "name": "uid", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's unique identifier" + } + }, + { + "name": "attributes", + "type": { + "type": "object", + "name": "AdminUserAttributes", + "properties": [ + { + "name": "app_metadata", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's application specific metadata. This maps to the `auth.users.app_metadata` column.\n\nOnly a service role can modify.\n\nThe `app_metadata` should be a JSON object that includes app-specific info, such as identity providers, roles, and other\naccess control information." + } + }, + { + "name": "ban_duration", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Determines how long a user is banned for.\n\nThe format for the ban duration follows a strict sequence of decimal numbers with a unit suffix.\nValid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\".\n\nFor example, some possible durations include: '300ms', '2h45m'.\n\nSetting the ban duration to 'none' lifts the ban on the user." + } + }, + { + "name": "current_password", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The user's current password\n\nThis is only ever present when the user is resetting\ntheir password and GOTRUE_SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD is true." + } + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The user's email." + } + }, + { + "name": "email_confirm", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Sets the user's email as confirmed when true, or unconfirmed when false.\n\nOnly a service role can modify." + } + }, + { + "name": "id", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The `id` for the user.\n\nAllows you to overwrite the default `id` set for the user." + } + }, + { + "name": "nonce", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The nonce sent for reauthentication if the user's password is to be updated.\n\nCall reauthenticate() to obtain the nonce first." + } + }, + { + "name": "password", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The user's password." + } + }, + { + "name": "password_hash", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The `password_hash` for the user's password.\n\nAllows you to specify a password hash for the user. This is useful for migrating a user's password hash from another service.\n\nSupports bcrypt, scrypt (firebase), and argon2 password hashes." + } + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The user's phone." + } + }, + { + "name": "phone_confirm", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Sets the user's phone as confirmed when true, or unconfirmed when false.\n\nOnly a service role can modify." + } + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The `role` claim set in the user's access token JWT.\n\nWhen a user signs up, this role is set to `authenticated` by default. You should only modify the `role` if you need to provision several levels of admin access that have different permissions on individual columns in your database.\n\nSetting this role to `service_role` is not recommended as it grants the user admin privileges." + } + }, + { + "name": "user_metadata", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.\n\n\nThe `user_metadata` should be a JSON object that includes user-specific info, such as their first and last name.\n\nNote: When using the GoTrueAdminApi and wanting to modify a user's metadata,\nthis attribute is used instead of UserAttributes data." + } + } + ] + }, + "comment": { + "shortText": "The data you want to update.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "UserResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Updates the user data. Changes are applied directly without confirmation flows.", + "text": "**Important:** This is a server-side operation and does **not** trigger client-side\n`onAuthStateChange` listeners. The admin API has no connection to client state.\n\nTo sync changes to the client after calling this method:\n1. On the client, call `supabase.auth.refreshSession()` to fetch the updated user data\n2. This will trigger the `TOKEN_REFRESHED` event and notify all listeners", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```typescript\n// Server-side (Edge Function)\nconst { data, error } = await supabase.auth.admin.updateUserById(\n userId,\n { user_metadata: { preferences: { theme: 'dark' } } }\n)\n\n// Client-side (to sync the changes)\nconst { data, error } = await supabase.auth.refreshSession()\n// onAuthStateChange listeners will now be notified with updated user\n```" + }, + { + "id": "updates-a-user-s-email", + "name": "Updates a user's email", + "code": "```js\nconst { data: user, error } = await supabase.auth.admin.updateUserById(\n '11111111-1111-1111-1111-111111111111',\n { email: 'new@email.com' }\n)\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"new@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"recovery_sent_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "updates-a-user-s-password", + "name": "Updates a user's password", + "code": "```js\nconst { data: user, error } = await supabase.auth.admin.updateUserById(\n '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4',\n { password: 'new_password' }\n)\n```" + }, + { + "id": "updates-a-user-s-metadata", + "name": "Updates a user's metadata", + "code": "```js\nconst { data: user, error } = await supabase.auth.admin.updateUserById(\n '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4',\n { user_metadata: { hello: 'world' } }\n)\n```" + }, + { + "id": "updates-a-user-s-app-metadata", + "name": "Updates a user's app_metadata", + "code": "```js\nconst { data: user, error } = await supabase.auth.admin.updateUserById(\n '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4',\n { app_metadata: { plan: 'trial' } }\n)\n```" + }, + { + "id": "confirms-a-user-s-email-address", + "name": "Confirms a user's email address", + "code": "```js\nconst { data: user, error } = await supabase.auth.admin.updateUserById(\n '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4',\n { email_confirm: true }\n)\n```" + }, + { + "id": "confirms-a-user-s-phone-number", + "name": "Confirms a user's phone number", + "code": "```js\nconst { data: user, error } = await supabase.auth.admin.updateUserById(\n '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4',\n { phone_confirm: true }\n)\n```" + }, + { + "id": "ban-a-user-for-100-years", + "name": "Ban a user for 100 years", + "code": "```js\nconst { data: user, error } = await supabase.auth.admin.updateUserById(\n '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4',\n { ban_duration: '876000h' }\n)\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.constructor": { + "name": "@supabase/supabase-js.GoTrueClient.constructor", + "params": [ + { + "name": "options", + "type": { + "name": "GoTrueClientOptions", + "type": "object", + "properties": [ + { + "name": "autoRefreshToken", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "debug", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "boolean" + }, + { + "type": "function", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "args", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "any" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + ] + }, + "isOptional": true + }, + { + "name": "detectSessionInUrl", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "boolean" + }, + { + "type": "function", + "params": [ + { + "name": "url", + "type": { + "type": "nameOnly", + "name": "URL" + } + }, + { + "name": "params", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "boolean" + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Set to \"true\" if you want to automatically detect OAuth grants in the URL and sign in the user.\nSet to \"false\" to disable automatic detection.\nSet to a function to provide custom logic for determining if a URL contains a Supabase auth callback.\nThe function receives the current URL and parsed parameters, and should return true if the URL\nshould be processed as a Supabase auth callback, or false to ignore it.\n\nThis is useful when your app uses other OAuth providers (e.g., Facebook Login) that also return\naccess_token in the URL fragment, which would otherwise be incorrectly intercepted by Supabase Auth.", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\ndetectSessionInUrl: (url, params) => {\n // Ignore Facebook OAuth redirects\n if (url.pathname === '/facebook/redirect') return false\n // Use default detection for other URLs\n return Boolean(params.access_token || params.error_description)\n}\n```" + } + ] + } + }, + { + "name": "experimental", + "type": { + "name": "ExperimentalFeatureFlags", + "type": "object", + "properties": [ + { + "name": "passkey", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Enables passkey support:\n - `auth.signInWithPasskey()`, `auth.registerPasskey()`\n - `auth.passkey.*`\n - `auth.admin.passkey.*`\n\nDefaults to `false`. Calling any passkey method while this flag is\ndisabled throws a descriptive error at call time." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Opt-in flags for experimental features. These APIs may change without\nnotice and are disabled by default.", + "tags": [ + { + "tag": "experimental", + "text": "" + } + ] + } + }, + { + "name": "fetch", + "type": { + "type": "nameOnly", + "name": "Fetch" + }, + "isOptional": true + }, + { + "name": "flowType", + "type": { + "type": "union", + "name": "AuthFlowType", + "subTypes": [ + { + "type": "literal", + "value": "implicit" + }, + { + "type": "literal", + "value": "pkce" + }, + null + ] + }, + "isOptional": true + }, + { + "name": "hasCustomAuthorizationHeader", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Set to \"true\" if there is a custom authorization header set globally.", + "tags": [ + { + "tag": "experimental", + "text": "" + } + ] + } + }, + { + "name": "headers", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true + }, + { + "name": "lock", + "type": { + "name": "LockFunc", + "type": "function", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Name of the lock to be acquired." + } + }, + { + "name": "acquireTimeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "If negative, no timeout should occur. If positive it\n should throw an Error with an `isAcquireTimeout`\n property set to true if the operation fails to be\n acquired after this much time (ms)." + } + }, + { + "name": "fn", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "R" + } + } + } + }, + "comment": { + "shortText": "The operation to execute when the lock is acquired." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "R" + } + } + } + }, + "isOptional": true, + "comment": { + "shortText": "Provide your own locking mechanism based on the environment. By default\nthe client coordinates refreshes itself (single-flight via\n`refreshingDeferred` + commit guard) and relies on the GoTrue server to\nresolve cross-tab refresh races. Passing a custom lock opts into a\nlegacy path that wraps every auth operation in your supplied lock — this\npath is preserved for backwards compatibility (typically React Native\n`processLock` or Node multi-process setups)." + } + }, + { + "name": "lockAcquireTimeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "The maximum time in milliseconds to wait for acquiring the custom lock\nsupplied via the `lock` option. Only consulted when a custom `lock` is\npassed — the default lockless path doesn't use this timeout." + } + }, + { + "name": "persistSession", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "skipAutoInitialize", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If true, skips automatic initialization in constructor. Useful for SSR\ncontexts where initialization timing must be controlled to prevent race\nconditions with HTTP response generation." + } + }, + { + "name": "storage", + "type": { + "type": "nameOnly", + "name": "SupportedStorage" + }, + "isOptional": true + }, + { + "name": "storageKey", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "throwOnError", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If there is an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response." + } + }, + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "userStorage", + "type": { + "type": "nameOnly", + "name": "SupportedStorage" + }, + "isOptional": true, + "comment": { + "shortText": "Stores the user object in a separate storage location from the rest of the session data. When non-null, `storage` will only store a JSON object containing the access and refresh token and some adjacent metadata, while `userStorage` will only contain the user object under the key `storageKey + '-user'`.\n\nWhen this option is set and cookie storage is used, `getSession()` and other functions that load a session from the cookie store might not return back a user. It's very important to always use `getUser()` to fetch a user object in those scenarios.", + "tags": [ + { + "tag": "experimental", + "text": "" + } + ] + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "GoTrueClient" + } + }, + "comment": { + "shortText": "Create a new client for use in the browser.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst { data, error } = await supabase.auth.getUser()\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport { GoTrueClient } from '@supabase/auth-js'\n\nconst auth = new GoTrueClient({\n url: 'https://xyzcompany.supabase.co/auth/v1',\n headers: { apikey: 'your-publishable-key' },\n storageKey: 'supabase-auth',\n})\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient._refreshSession": { + "name": "@supabase/supabase-js.GoTrueClient._refreshSession", + "params": [ + { + "name": "currentSession", + "type": { + "type": "object", + "properties": [ + { + "name": "refresh_token", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": { + "type": "literal", + "value": "bearer" + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + { + "type": "literal", + "value": null + } + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + { + "type": "literal", + "value": null + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + } + }, + "@supabase/supabase-js.GoTrueClient._setSession": { + "name": "@supabase/supabase-js.GoTrueClient._setSession", + "params": [ + { + "name": "currentSession", + "type": { + "type": "object", + "properties": [ + { + "name": "access_token", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "refresh_token", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + "[Circular]" + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "[Circular]" + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + } + }, + "@supabase/supabase-js.GoTrueClient._signOut": { + "name": "@supabase/supabase-js.GoTrueClient._signOut", + "params": [ + { + "type": { + "name": "SignOut", + "type": "object", + "properties": [ + { + "name": "scope", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "global" + }, + { + "type": "literal", + "value": "local" + }, + { + "type": "literal", + "value": "others" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Determines which sessions should be\nlogged out. Global means all\nsessions by this account. Local\nmeans only this session. Others\nmeans all other sessions except the\ncurrent one. When using others,\nthere is no sign-out event fired on\nthe current session!" + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "object", + "properties": [ + { + "name": "error", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "nameOnly", + "name": "AuthError" + } + ] + } + } + ] + } + } + } + }, + "@supabase/supabase-js.GoTrueClient._updateUser": { + "name": "@supabase/supabase-js.GoTrueClient._updateUser", + "params": [ + { + "name": "attributes", + "type": { + "type": "object", + "name": "UserAttributes", + "properties": [ + { + "name": "current_password", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The user's current password\n\nThis is only ever present when the user is resetting\ntheir password and GOTRUE_SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD is true." + } + }, + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "object" + }, + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.\n\nThe `data` should be a JSON object that includes user-specific info, such as their first and last name." + } + }, + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The user's email." + } + }, + { + "name": "nonce", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The nonce sent for reauthentication if the user's password is to be updated.\n\nCall reauthenticate() to obtain the nonce first." + } + }, + { + "name": "password", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The user's password." + } + }, + { + "name": "phone", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The user's phone." + } + } + ] + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "emailRedirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "UserResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + } + }, + "@supabase/supabase-js.GoTrueClient.dispose": { + "name": "@supabase/supabase-js.GoTrueClient.dispose", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "Tears down the client's background work: stops the auto-refresh interval,\nremoves the `visibilitychange` listener, closes the cross-tab\n`BroadcastChannel`, and clears registered `onAuthStateChange` subscribers.\n\nCall this from cleanup hooks when the client is being replaced before\nits JS realm is destroyed. React Strict Mode and HMR are the common\ncases. Any in-flight `fetch` calls continue to completion and may still\nwrite to storage; dispose doesn't abort them or erase storage.\n\nLifecycle caveat: because in-flight refreshes are not aborted, a\ndisposed instance can still persist a rotated session to storage after\n`dispose()` returns. A subsequent `createClient` against the same\n`storageKey` will pick up that session on its next read. If you need\nstrict isolation between client lifecycles, await any pending auth\noperation before calling `dispose()` (or change the `storageKey` for\nthe replacement client).\n\nSafe to call repeatedly.", + "examples": [ + { + "id": "cleanup-on-react-unmount", + "name": "Cleanup on React unmount", + "code": "```ts\nuseEffect(() => {\n const client = createClient(...)\n return () => { client.auth.dispose() }\n}, [])\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.exchangeCodeForSession": { + "name": "@supabase/supabase-js.GoTrueClient.exchangeCodeForSession", + "params": [ + { + "name": "authCode", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthTokenResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Log in an existing user by exchanging an Auth Code issued during the PKCE flow.", + "text": "- Used when `flowType` is set to `pkce` in client options.", + "examples": [ + { + "id": "exchange-auth-code", + "name": "Exchange Auth Code", + "code": "```js\nsupabase.auth.exchangeCodeForSession('34e770dd-9ff9-416c-87fa-43b31d7ef225')\n```", + "response": "```json\n{\n \"data\": {\n session: {\n access_token: '',\n token_type: 'bearer',\n expires_in: 3600,\n expires_at: 1700000000,\n refresh_token: '',\n user: {\n id: '11111111-1111-1111-1111-111111111111',\n aud: 'authenticated',\n role: 'authenticated',\n email: 'example@email.com'\n email_confirmed_at: '2024-01-01T00:00:00Z',\n phone: '',\n confirmation_sent_at: '2024-01-01T00:00:00Z',\n confirmed_at: '2024-01-01T00:00:00Z',\n last_sign_in_at: '2024-01-01T00:00:00Z',\n app_metadata: {\n \"provider\": \"email\",\n \"providers\": [\n \"email\",\n \"\"\n ]\n },\n user_metadata: {\n email: 'email@email.com',\n email_verified: true,\n full_name: 'User Name',\n iss: '',\n name: 'User Name',\n phone_verified: false,\n provider_id: '',\n sub: ''\n },\n identities: [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"email@example.com\"\n },\n {\n \"identity_id\": \"33333333-3333-3333-3333-333333333333\",\n \"id\": \"\",\n \"user_id\": \"\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": true,\n \"full_name\": \"User Name\",\n \"iss\": \"\",\n \"name\": \"User Name\",\n \"phone_verified\": false,\n \"provider_id\": \"\",\n \"sub\": \"\"\n },\n \"provider\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n is_anonymous: false\n },\n provider_token: '',\n provider_refresh_token: ''\n },\n user: {\n id: '11111111-1111-1111-1111-111111111111',\n aud: 'authenticated',\n role: 'authenticated',\n email: 'example@email.com',\n email_confirmed_at: '2024-01-01T00:00:00Z',\n phone: '',\n confirmation_sent_at: '2024-01-01T00:00:00Z',\n confirmed_at: '2024-01-01T00:00:00Z',\n last_sign_in_at: '2024-01-01T00:00:00Z',\n app_metadata: {\n provider: 'email',\n providers: [\n \"email\",\n \"\"\n ]\n },\n user_metadata: {\n email: 'email@email.com',\n email_verified: true,\n full_name: 'User Name',\n iss: '',\n name: 'User Name',\n phone_verified: false,\n provider_id: '',\n sub: ''\n },\n identities: [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"email@example.com\"\n },\n {\n \"identity_id\": \"33333333-3333-3333-3333-333333333333\",\n \"id\": \"\",\n \"user_id\": \"\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": true,\n \"full_name\": \"User Name\",\n \"iss\": \"\",\n \"name\": \"User Name\",\n \"phone_verified\": false,\n \"provider_id\": \"\",\n \"sub\": \"\"\n },\n \"provider\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n is_anonymous: false\n },\n redirectType: null\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.getClaims": { + "name": "@supabase/supabase-js.GoTrueClient.getClaims", + "params": [ + { + "name": "jwt", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "An optional specific JWT you wish to verify, not the one you\n can obtain from #getSession." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "allowExpired", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If set to `true` the `exp` claim will not be validated against the current time." + } + }, + { + "name": "jwks", + "type": { + "type": "object", + "properties": [ + { + "name": "keys", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "JWK", + "properties": [ + { + "name": "alg", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "key_ops", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + }, + { + "name": "kid", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "kty", + "type": { + "type": "union", + "subTypes": [ + null, + { + "type": "literal", + "value": "RSA" + }, + { + "type": "literal", + "value": "EC" + }, + { + "type": "literal", + "value": "oct" + } + ] + } + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "If set, this JSON Web Key Set is going to have precedence over the cached value available on the server." + } + }, + { + "name": "keys", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "JWK", + "properties": [ + { + "name": "alg", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "key_ops", + "type": { + "type": "array", + "elemType": "[Circular]" + } + }, + { + "name": "kid", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "kty", + "type": { + "type": "union", + "subTypes": [ + null, + "[Circular]", + "[Circular]", + "[Circular]" + ] + } + } + ] + } + }, + "isOptional": true, + "comment": { + "shortText": "" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Various additional options that allow you to customize the\n behavior of this method." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "claims", + "type": { + "type": "object", + "name": "JwtPayload", + "properties": [ + { + "name": "aal", + "type": { + "type": "union", + "name": "AuthenticatorAssuranceLevels", + "subTypes": [ + { + "type": "literal", + "value": "aal1" + }, + { + "type": "literal", + "value": "aal2" + }, + null + ] + } + }, + { + "name": "amr", + "type": { + "type": "union", + "subTypes": [ + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + { + "type": "array", + "elemType": { + "type": "object", + "name": "AMREntry", + "properties": [ + { + "name": "method", + "type": { + "type": "union", + "name": "AMRMethod", + "subTypes": [ + { + "type": "nameOnly", + "name": "['number']" + }, + null + ] + }, + "comment": { + "shortText": "Authentication method name." + } + }, + { + "name": "timestamp", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "Timestamp when the method was successfully used. Represents number of\nseconds since 1st January 1970 (UNIX epoch) in UTC." + } + } + ] + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Authentication Method References.\nSupports both RFC-8176 compliant format (string[]) and detailed format (AMREntry[]).\n- String format: ['password', 'otp'] - RFC-8176 compliant\n- Object format: [{ method: 'password', timestamp: 1234567890 }] - includes timestamps" + } + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + }, + "isOptional": true + }, + { + "name": "aud", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "exp", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "iat", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "is_anonymous", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "iss", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "jti", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "nbf", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "phone", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "ref", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "role", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "session_id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "sub", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + }, + "isOptional": true + } + ] + } + }, + { + "name": "header", + "type": { + "name": "JwtHeader", + "type": "object", + "properties": [ + { + "name": "alg", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "RS256" + }, + { + "type": "literal", + "value": "ES256" + }, + { + "type": "literal", + "value": "HS256" + }, + null + ] + } + }, + { + "name": "kid", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "typ", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "signature", + "type": { + "type": "nameOnly", + "name": "Uint8Array" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Extracts the JWT claims present in the access token by first verifying the\nJWT against the server's JSON Web Key Set endpoint\n`/.well-known/jwks.json` which is often cached, resulting in significantly\nfaster responses. Prefer this method over #getUser which always\nsends a request to the Auth server for each JWT.\n\nIf the project is not using an asymmetric JWT signing key (like ECC or\nRSA) it always sends a request to the Auth server (similar to #getUser) to verify the JWT.", + "text": "- Parses the user's [access token](/docs/guides/auth/sessions#access-token-jwt-claims) as a [JSON Web Token (JWT)](/docs/guides/auth/jwts) and returns its components if valid and not expired.\n- If your project is using asymmetric JWT signing keys, then the verification is done locally usually without a network request using the [WebCrypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API).\n- A network request is sent to your project's JWT signing key discovery endpoint `https://project-id.supabase.co/auth/v1/.well-known/jwks.json`, which is cached locally. If your environment is ephemeral, such as a Lambda function that is destroyed after every request, a network request will be sent for each new invocation. Supabase provides a network-edge cache providing fast responses for these situations.\n- If the user's access token is about to expire when calling this function, the user's session will first be refreshed before validating the JWT.\n- If your project is using a symmetric secret to sign the JWT, it always sends a request similar to `getUser()` to validate the JWT at the server before returning the decoded token. This is also used if the WebCrypto API is not available in the environment. Make sure you polyfill it in such situations.\n- The returned claims can be customized per project using the [Custom Access Token Hook](/docs/guides/auth/auth-hooks/custom-access-token-hook).", + "examples": [ + { + "id": "get-jwt-claims-header-and-signature", + "name": "Get JWT claims, header and signature", + "code": "```js\nconst { data, error } = await supabase.auth.getClaims()\n```", + "response": "```json\n{\n \"data\": {\n \"claims\": {\n \"aal\": \"aal1\",\n \"amr\": [{\n \"method\": \"email\",\n \"timestamp\": 1715766000\n }],\n \"app_metadata\": {},\n \"aud\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"exp\": 1715769600,\n \"iat\": 1715766000,\n \"is_anonymous\": false,\n \"iss\": \"https://project-id.supabase.co/auth/v1\",\n \"phone\": \"+13334445555\",\n \"role\": \"authenticated\",\n \"session_id\": \"11111111-1111-1111-1111-111111111111\",\n \"sub\": \"11111111-1111-1111-1111-111111111111\",\n \"user_metadata\": {}\n },\n \"header\": {\n \"alg\": \"RS256\",\n \"typ\": \"JWT\",\n \"kid\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"signature\": [/** Uint8Array */],\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.getSession": { + "name": "@supabase/supabase-js.GoTrueClient.getSession", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "literal", + "value": null + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "literal", + "value": null + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Returns the session, refreshing it if necessary.\n\nThe session returned can be null if the session is not detected which can happen in the event a user is not signed-in or has logged out.\n\n**IMPORTANT:** This method loads values directly from the storage attached\nto the client. If that storage is based on request cookies for example,\nthe values in it may not be authentic and therefore it's strongly advised\nagainst using this method and its results in such circumstances. A warning\nwill be emitted if this is detected. Use #getUser() instead.", + "text": "- Since the introduction of [asymmetric JWT signing keys](/docs/guides/auth/signing-keys), this method is considered low-level and we encourage you to use `getClaims()` or `getUser()` instead.\n- Retrieves the current [user session](/docs/guides/auth/sessions) from the storage medium (local storage, cookies).\n- The session contains an access token (signed JWT), a refresh token and the user object.\n- If the session's access token is expired or is about to expire, this method will use the refresh token to refresh the session.\n- When using in a browser, or you've called `startAutoRefresh()` in your environment (React Native, etc.) this function always returns a valid access token without refreshing the session itself, as this is done in the background. This function returns very fast.\n- **IMPORTANT SECURITY NOTICE:** If using an insecure storage medium, such as cookies or request headers, the user object returned by this function **must not be trusted**. Always verify the JWT using `getClaims()` or your own JWT verification library to securely establish the user's identity and access. You can also use `getUser()` to fetch the user object directly from the Auth server for this purpose.\n- Cross-tab refresh races are handled by the GoTrue server (the rotated token from the first tab is returned to subsequent tabs via the parent-of-active mechanism), so no client-side serialization is needed.", + "examples": [ + { + "id": "get-the-session-data", + "name": "Get the session data", + "code": "```js\nconst { data, error } = await supabase.auth.getSession()\n```", + "response": "```json\n{\n \"data\": {\n \"session\": {\n \"access_token\": \"\",\n \"token_type\": \"bearer\",\n \"expires_in\": 3600,\n \"expires_at\": 1700000000,\n \"refresh_token\": \"\",\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n }\n }\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.getUser": { + "name": "@supabase/supabase-js.GoTrueClient.getUser", + "params": [ + { + "name": "jwt", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Takes in an optional access token JWT. If no JWT is provided, the JWT from the current session is used." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "UserResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Gets the current user details if there is an existing session. This method\nperforms a network request to the Supabase Auth server, so the returned\nvalue is authentic and can be used to base authorization rules on.", + "text": "- This method fetches the user object from the database instead of local session.\n- This method is useful for checking if the user is authorized because it validates the user's access token JWT on the server.\n- Should always be used when checking for user authorization on the server. On the client, you can instead use `getSession().session.user` for faster results. `getSession` is insecure on the server.", + "examples": [ + { + "id": "get-the-logged-in-user-with-the-current-existing-session", + "name": "Get the logged in user with the current existing session", + "code": "```js\nconst { data: { user } } = await supabase.auth.getUser()\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "get-the-logged-in-user-with-a-custom-access-token-jwt", + "name": "Get the logged in user with a custom access token jwt", + "code": "```js\nconst { data: { user } } = await supabase.auth.getUser(jwt)\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.getUserIdentities": { + "name": "@supabase/supabase-js.GoTrueClient.getUserIdentities", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Gets all the identities linked to a user.", + "text": "- The user needs to be signed in to call `getUserIdentities()`.", + "examples": [ + { + "id": "returns-a-list-of-identities-linked-to-the-user", + "name": "Returns a list of identities linked to the user", + "code": "```js\nconst { data, error } = await supabase.auth.getUserIdentities()\n```", + "response": "```json\n{\n \"data\": {\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"2024-01-01T00:00:00Z\",\n \"user_id\": \"2024-01-01T00:00:00Z\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ]\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.initialize": { + "name": "@supabase/supabase-js.GoTrueClient.initialize", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "name": "InitializeResult", + "type": "object", + "properties": [ + { + "name": "error", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "AuthError" + }, + { + "type": "literal", + "value": null + } + ] + } + } + ] + } + } + }, + "comment": { + "shortText": "Initializes the client session either from the url or from storage.\nThis method is automatically called when instantiating the client, but should also be called\nmanually when checking for an error from an auth redirect (oauth, magiclink, password recovery, etc)." + } + }, + "@supabase/supabase-js.GoTrueClient.isThrowOnErrorEnabled": { + "name": "@supabase/supabase-js.GoTrueClient.isThrowOnErrorEnabled", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "boolean" + } + }, + "comment": { + "shortText": "Returns whether error throwing mode is enabled for this client." + } + }, + "@supabase/supabase-js.GoTrueClient.linkIdentity": { + "name": "@supabase/supabase-js.GoTrueClient.linkIdentity", + "params": [ + { + "name": "credentials", + "type": { + "name": "SignInWithOAuthCredentials", + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "queryParams", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "An object of query params" + } + }, + { + "name": "redirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "A URL to send the user to after they are confirmed." + } + }, + { + "name": "scopes", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "A space-separated list of scopes granted to the OAuth application." + } + }, + { + "name": "skipBrowserRedirect", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If set to true does not immediately redirect the current browser context to visit the OAuth authorization page for the provider." + } + } + ] + }, + "isOptional": true + }, + { + "name": "provider", + "type": { + "type": "union", + "name": "Provider", + "subTypes": [ + { + "type": "literal", + "value": "apple" + }, + { + "type": "literal", + "value": "azure" + }, + { + "type": "literal", + "value": "bitbucket" + }, + { + "type": "literal", + "value": "discord" + }, + { + "type": "literal", + "value": "facebook" + }, + { + "type": "literal", + "value": "figma" + }, + { + "type": "literal", + "value": "github" + }, + { + "type": "literal", + "value": "gitlab" + }, + { + "type": "literal", + "value": "google" + }, + { + "type": "literal", + "value": "kakao" + }, + { + "type": "literal", + "value": "keycloak" + }, + { + "type": "literal", + "value": "linkedin" + }, + { + "type": "literal", + "value": "linkedin_oidc" + }, + { + "type": "literal", + "value": "notion" + }, + { + "type": "literal", + "value": "slack" + }, + { + "type": "literal", + "value": "slack_oidc" + }, + { + "type": "literal", + "value": "spotify" + }, + { + "type": "literal", + "value": "twitch" + }, + { + "type": "literal", + "value": "twitter" + }, + { + "type": "literal", + "value": "x" + }, + { + "type": "literal", + "value": "workos" + }, + { + "type": "literal", + "value": "zoom" + }, + { + "type": "literal", + "value": "fly" + }, + null + ] + }, + "comment": { + "shortText": "One of the providers supported by GoTrue." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "OAuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "provider", + "type": { + "type": "union", + "name": "Provider", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + }, + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "provider", + "type": { + "type": "union", + "name": "Provider", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + }, + { + "name": "url", + "type": { + "type": "literal", + "value": null + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Links an oauth identity to an existing user.\nThis method supports the PKCE flow." + }, + "altSignatures": [ + { + "params": [ + { + "name": "credentials", + "type": { + "name": "SignInWithIdTokenCredentials", + "type": "object", + "properties": [ + { + "name": "access_token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "If the ID token contains an `at_hash` claim, then the hash of this value is compared to the value in the ID token." + } + }, + { + "name": "nonce", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "If the ID token contains a `nonce` claim, then the hash of this value is compared to the value in the ID token." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + } + ] + }, + "isOptional": true + }, + { + "name": "provider", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "google" + }, + { + "type": "literal", + "value": "apple" + }, + { + "type": "literal", + "value": "azure" + }, + { + "type": "literal", + "value": "facebook" + }, + { + "type": "literal", + "value": "kakao" + }, + null, + null + ] + }, + "comment": { + "shortText": "Provider name or OIDC `iss` value identifying which provider should be used to verify the provided token. Supported names: `google`, `apple`, `azure`, `facebook`, `kakao`. Use the `custom:` prefix for custom OIDC providers (e.g. `custom:my-oidc-provider`)." + } + }, + { + "name": "token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "OIDC ID token issued by the specified provider. The `iss` claim in the ID token must match the supplied provider. Some ID tokens contain an `at_hash` which require that you provide an `access_token` value to be accepted properly. If the token contains a `nonce` claim you must supply the nonce used to obtain the ID token." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthTokenResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + } + } + ] + }, + "@supabase/supabase-js.GoTrueClient.onAuthStateChange": { + "name": "@supabase/supabase-js.GoTrueClient.onAuthStateChange", + "params": [ + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "event", + "type": { + "type": "union", + "name": "AuthChangeEvent", + "subTypes": [ + { + "type": "literal", + "value": "INITIAL_SESSION" + }, + { + "type": "literal", + "value": "PASSWORD_RECOVERY" + }, + { + "type": "literal", + "value": "SIGNED_IN" + }, + { + "type": "literal", + "value": "SIGNED_OUT" + }, + { + "type": "literal", + "value": "TOKEN_REFRESHED" + }, + { + "type": "literal", + "value": "USER_UPDATED" + }, + { + "type": "literal", + "value": "MFA_CHALLENGE_VERIFIED", + "name": "AuthChangeEventMFA" + } + ] + } + }, + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "A callback function to be invoked when an auth event happens." + } + } + ], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "subscription", + "type": { + "type": "object", + "name": "Subscription", + "properties": [ + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "event", + "type": { + "type": "union", + "name": "AuthChangeEvent", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + } + }, + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "The function to call every time there is an event. eg: (eventName) => {}" + } + }, + { + "name": "id", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "symbol" + } + ] + }, + "comment": { + "shortText": "A unique identifier for this subscription, set by the client.\nThis is an internal identifier used for managing callbacks and should not be\nrelied upon by application code. Use the unsubscribe() method to remove listeners." + } + }, + { + "name": "unsubscribe", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "Call this to remove the listener." + } + } + ] + } + } + ] + } + } + ] + } + }, + "comment": { + "shortText": "Receive a notification every time an auth event happens.\nSafe to use without an async function as callback." + }, + "altSignatures": [ + { + "params": [ + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "event", + "type": { + "type": "union", + "name": "AuthChangeEvent", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + } + }, + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "intrinsic", + "name": "void" + } + } + } + }, + "comment": { + "shortText": "A callback function to be invoked when an auth event happens." + } + } + ], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "subscription", + "type": { + "type": "object", + "name": "Subscription", + "properties": [ + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "event", + "type": { + "type": "union", + "name": "AuthChangeEvent", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]" + ] + } + }, + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + ] + } + } + ], + "ret": { + "type": "[Circular]" + } + }, + "comment": { + "shortText": "The function to call every time there is an event. eg: (eventName) => {}" + } + }, + { + "name": "id", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "A unique identifier for this subscription, set by the client.\nThis is an internal identifier used for managing callbacks and should not be\nrelied upon by application code. Use the unsubscribe() method to remove listeners." + } + }, + { + "name": "unsubscribe", + "type": { + "type": "function", + "params": [], + "ret": { + "type": "[Circular]" + } + }, + "comment": { + "shortText": "Call this to remove the listener." + } + } + ] + } + } + ] + } + } + ] + } + } + } + ] + }, + "@supabase/supabase-js.GoTrueClient.reauthenticate": { + "name": "@supabase/supabase-js.GoTrueClient.reauthenticate", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + "[Circular]" + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "[Circular]" + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Sends a reauthentication OTP to the user's email or phone number.\nRequires the user to be signed-in.", + "text": "- This method is used together with `updateUser()` when a user's password needs to be updated.\n- If you require your user to reauthenticate before updating their password, you need to enable the **Secure password change** option in your [project's email provider settings](/dashboard/project/_/auth/providers).\n- A user is only require to reauthenticate before updating their password if **Secure password change** is enabled and the user **hasn't recently signed in**. A user is deemed recently signed in if the session was created in the last 24 hours.\n- This method will send a nonce to the user's email. If the user doesn't have a confirmed email address, the method will send the nonce to the user's confirmed phone number instead.\n- After receiving the OTP, include it as the `nonce` in your `updateUser()` call to finalize the password change.", + "examples": [ + { + "id": "send-reauthentication-nonce", + "name": "Send reauthentication nonce", + "code": "```js\nconst { error } = await supabase.auth.reauthenticate()\n```", + "description": "Sends a reauthentication nonce to the user's email or phone number." + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.refreshSession": { + "name": "@supabase/supabase-js.GoTrueClient.refreshSession", + "params": [ + { + "name": "currentSession", + "type": { + "type": "object", + "properties": [ + { + "name": "refresh_token", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The current session. If passed in, it must contain a refresh token." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + "[Circular]" + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "[Circular]" + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Returns a new session, regardless of expiry status.\nTakes in an optional current session. If not passed in, then refreshSession() will attempt to retrieve it from getSession().\nIf the current session's refresh token is invalid, an error will be thrown.", + "text": "- This method will refresh and return a new session whether the current one is expired or not.", + "examples": [ + { + "id": "refresh-session-using-the-current-session", + "name": "Refresh session using the current session", + "code": "```js\nconst { data, error } = await supabase.auth.refreshSession()\nconst { session, user } = data\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n },\n \"session\": {\n \"access_token\": \"\",\n \"token_type\": \"bearer\",\n \"expires_in\": 3600,\n \"expires_at\": 1700000000,\n \"refresh_token\": \"\",\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n }\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "refresh-session-using-a-refresh-token", + "name": "Refresh session using a refresh token", + "code": "```js\nconst { data, error } = await supabase.auth.refreshSession({ refresh_token })\nconst { session, user } = data\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.registerPasskey": { + "name": "@supabase/supabase-js.GoTrueClient.registerPasskey", + "params": [ + { + "name": "credentials", + "type": { + "name": "RegisterPasskeyCredentials", + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyRegistrationVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "PasskeyMetadata", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "friendly_name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Register a passkey for the current authenticated user. Handles the full WebAuthn ceremony:\n1. Fetches registration challenge from server\n2. Prompts user via navigator.credentials.create()\n3. Verifies credential with server\n\nRequires an active session. Requires `auth.experimental.passkey: true`." + } + }, + "@supabase/supabase-js.GoTrueClient.resend": { + "name": "@supabase/supabase-js.GoTrueClient.resend", + "params": [ + { + "name": "credentials", + "type": { + "type": "union", + "name": "ResendParams", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "emailRedirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "A URL to send the user to after they have signed-in." + } + } + ] + }, + "isOptional": true + }, + { + "name": "type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "signup" + }, + { + "type": "literal", + "value": "email_change" + } + ] + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + } + ] + }, + "isOptional": true + }, + { + "name": "phone", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "sms" + }, + { + "type": "literal", + "value": "phone_change" + } + ] + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthOtpResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "messageId", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "literal", + "value": null + } + ] + }, + "isOptional": true + }, + { + "name": "session", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "user", + "type": { + "type": "literal", + "value": null + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "messageId", + "type": "[Circular]" + }, + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Resends an existing signup confirmation email, email change email, SMS OTP or phone change OTP.", + "text": "- Resends a signup confirmation, email change or phone change email to the user.\n- Passwordless sign-ins can be resent by calling the `signInWithOtp()` method again.\n- Password recovery emails can be resent by calling the `resetPasswordForEmail()` method again.\n- This method will only resend an email or phone OTP to the user if there was an initial signup, email change or phone change request being made(note: For existing users signing in with OTP, you should use `signInWithOtp()` again to resend the OTP).\n- You can specify a redirect url when you resend an email link using the `emailRedirectTo` option.", + "examples": [ + { + "id": "resend-an-email-signup-confirmation", + "name": "Resend an email signup confirmation", + "code": "```js\nconst { error } = await supabase.auth.resend({\n type: 'signup',\n email: 'email@example.com',\n options: {\n emailRedirectTo: 'https://example.com/welcome'\n }\n})\n```", + "description": "Resends the email signup confirmation to the user" + }, + { + "id": "resend-a-phone-signup-confirmation", + "name": "Resend a phone signup confirmation", + "code": "```js\nconst { error } = await supabase.auth.resend({\n type: 'sms',\n phone: '1234567890'\n})\n```", + "description": "Resends the phone signup confirmation email to the user" + }, + { + "id": "resend-email-change-email", + "name": "Resend email change email", + "code": "```js\nconst { error } = await supabase.auth.resend({\n type: 'email_change',\n email: 'email@example.com'\n})\n```", + "description": "Resends the email change email to the user" + }, + { + "id": "resend-phone-change-otp", + "name": "Resend phone change OTP", + "code": "```js\nconst { error } = await supabase.auth.resend({\n type: 'phone_change',\n phone: '1234567890'\n})\n```", + "description": "Resends the phone change OTP to the user" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.resetPasswordForEmail": { + "name": "@supabase/supabase-js.GoTrueClient.resetPasswordForEmail", + "params": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The email address of the user." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "redirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The URL to send the user to after they click the password reset link." + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Sends a password reset request to an email address. This method supports the PKCE flow.", + "text": "- The password reset flow consist of 2 broad steps: (i) Allow the user to login via the password reset link; (ii) Update the user's password.\n- The `resetPasswordForEmail()` only sends a password reset link to the user's email.\nTo update the user's password, see [`updateUser()`](/docs/reference/javascript/auth-updateuser).\n- A `PASSWORD_RECOVERY` event will be emitted when the password recovery link is clicked.\nYou can use [`onAuthStateChange()`](/docs/reference/javascript/auth-onauthstatechange) to listen and invoke a callback function on these events.\n- When the user clicks the reset link in the email they are redirected back to your application.\nYou can configure the URL that the user is redirected to with the `redirectTo` parameter.\nSee [redirect URLs and wildcards](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls) to add additional redirect URLs to your project.\n- After the user has been redirected successfully, prompt them for a new password and call `updateUser()`:\n```js\nconst { data, error } = await supabase.auth.updateUser({\n password: new_password\n})\n```", + "examples": [ + { + "id": "reset-password", + "name": "Reset password", + "code": "```js\nconst { data, error } = await supabase.auth.resetPasswordForEmail(email, {\n redirectTo: 'https://example.com/update-password',\n})\n```", + "response": "```json\n{\n data: {}\n error: null\n}\n```" + }, + { + "id": "reset-password-react", + "name": "Reset password (React)", + "code": "```js\n/**\n * Step 1: Send the user an email to get a password reset token.\n * This email contains a link which sends the user back to your application.\n */\nconst { data, error } = await supabase.auth\n .resetPasswordForEmail('user@email.com')\n\n/**\n * Step 2: Once the user is redirected back to your application,\n * ask the user to reset their password.\n */\n useEffect(() => {\n supabase.auth.onAuthStateChange(async (event, session) => {\n if (event == \"PASSWORD_RECOVERY\") {\n const newPassword = prompt(\"What would you like your new password to be?\");\n const { data, error } = await supabase.auth\n .updateUser({ password: newPassword })\n\n if (data) alert(\"Password updated successfully!\")\n if (error) alert(\"There was an error updating your password.\")\n }\n })\n }, [])\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.setSession": { + "name": "@supabase/supabase-js.GoTrueClient.setSession", + "params": [ + { + "name": "currentSession", + "type": { + "type": "object", + "properties": [ + { + "name": "access_token", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "refresh_token", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "comment": { + "shortText": "The current session that minimally contains an access token and refresh token." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + "[Circular]" + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "[Circular]" + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Sets the session data from the current session. If the current session is expired, setSession will take care of refreshing it to obtain a new session.\nIf the refresh token or access token in the current session is invalid, an error will be thrown.", + "text": "- This method sets the session using an `access_token` and `refresh_token`.\n- If successful, a `SIGNED_IN` event is emitted.", + "examples": [ + { + "id": "set-the-session", + "name": "Set the session", + "code": "```js\n const { data, error } = await supabase.auth.setSession({\n access_token,\n refresh_token\n })\n```", + "description": "Sets the session data from an access_token and refresh_token, then returns an auth response or error.", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n },\n \"session\": {\n \"access_token\": \"\",\n \"refresh_token\": \"\",\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"11111111-1111-1111-1111-111111111111\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"2024-01-01T00:00:00Z\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n },\n \"token_type\": \"bearer\",\n \"expires_in\": 3500,\n \"expires_at\": 1700000000\n }\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.signInAnonymously": { + "name": "@supabase/supabase-js.GoTrueClient.signInAnonymously", + "params": [ + { + "name": "credentials", + "type": { + "name": "SignInAnonymouslyCredentials", + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "object" + }, + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.\n\nThe `data` should be a JSON object that includes user-specific info, such as their first and last name." + } + } + ] + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + "[Circular]" + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "[Circular]" + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a new anonymous user.", + "text": "- Returns an anonymous user\n- It is recommended to set up captcha for anonymous sign-ins to prevent abuse. You can pass in the captcha token in the `options` param.", + "examples": [ + { + "id": "create-an-anonymous-user", + "name": "Create an anonymous user", + "code": "```js\nconst { data, error } = await supabase.auth.signInAnonymously({\n options: {\n captchaToken\n }\n});\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"\",\n \"phone\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {},\n \"user_metadata\": {},\n \"identities\": [],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": true\n },\n \"session\": {\n \"access_token\": \"\",\n \"token_type\": \"bearer\",\n \"expires_in\": 3600,\n \"expires_at\": 1700000000,\n \"refresh_token\": \"\",\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"\",\n \"phone\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {},\n \"user_metadata\": {},\n \"identities\": [],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": true\n }\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "create-an-anonymous-user-with-custom-user-metadata", + "name": "Create an anonymous user with custom user metadata", + "code": "```js\nconst { data, error } = await supabase.auth.signInAnonymously({\n options: {\n data\n }\n})\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.signInWithIdToken": { + "name": "@supabase/supabase-js.GoTrueClient.signInWithIdToken", + "params": [ + { + "name": "credentials", + "type": { + "name": "SignInWithIdTokenCredentials", + "type": "object", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "If the ID token contains an `at_hash` claim, then the hash of this value is compared to the value in the ID token." + } + }, + { + "name": "nonce", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "If the ID token contains a `nonce` claim, then the hash of this value is compared to the value in the ID token." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + } + ] + }, + "isOptional": true + }, + { + "name": "provider", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + null, + null + ] + }, + "comment": { + "shortText": "Provider name or OIDC `iss` value identifying which provider should be used to verify the provided token. Supported names: `google`, `apple`, `azure`, `facebook`, `kakao`. Use the `custom:` prefix for custom OIDC providers (e.g. `custom:my-oidc-provider`)." + } + }, + { + "name": "token", + "type": "[Circular]", + "comment": { + "shortText": "OIDC ID token issued by the specified provider. The `iss` claim in the ID token must match the supplied provider. Some ID tokens contain an `at_hash` which require that you provide an `access_token` value to be accepted properly. If the token contains a `nonce` claim you must supply the nonce used to obtain the ID token." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthTokenResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Allows signing in with an OIDC ID token. The authentication provider used\nshould be enabled and configured.", + "text": "- Use an ID token to sign in.\n- Especially useful when implementing sign in using native platform dialogs in mobile or desktop apps using Sign in with Apple or Sign in with Google on iOS and Android.\n- You can also use Google's [One Tap](https://developers.google.com/identity/gsi/web/guides/display-google-one-tap) and [Automatic sign-in](https://developers.google.com/identity/gsi/web/guides/automatic-sign-in-sign-out) via this API.", + "examples": [ + { + "id": "sign-in-using-id-token", + "name": "Sign In using ID Token", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithIdToken({\n provider: 'google',\n token: 'your-id-token'\n})\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n ...\n },\n \"user_metadata\": {\n ...\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"provider\": \"google\",\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n },\n \"session\": {\n \"access_token\": \"\",\n \"token_type\": \"bearer\",\n \"expires_in\": 3600,\n \"expires_at\": 1700000000,\n \"refresh_token\": \"\",\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n ...\n },\n \"user_metadata\": {\n ...\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"provider\": \"google\",\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n }\n }\n },\n \"error\": null\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.signInWithOAuth": { + "name": "@supabase/supabase-js.GoTrueClient.signInWithOAuth", + "params": [ + { + "name": "credentials", + "type": { + "name": "SignInWithOAuthCredentials", + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "queryParams", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "An object of query params" + } + }, + { + "name": "redirectTo", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A URL to send the user to after they are confirmed." + } + }, + { + "name": "scopes", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A space-separated list of scopes granted to the OAuth application." + } + }, + { + "name": "skipBrowserRedirect", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "If set to true does not immediately redirect the current browser context to visit the OAuth authorization page for the provider." + } + } + ] + }, + "isOptional": true + }, + { + "name": "provider", + "type": { + "type": "union", + "name": "Provider", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + }, + "comment": { + "shortText": "One of the providers supported by GoTrue." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "OAuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "provider", + "type": { + "type": "union", + "name": "Provider", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + }, + { + "name": "url", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "provider", + "type": { + "type": "union", + "name": "Provider", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + }, + { + "name": "url", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Log in an existing user via a third-party provider.\nThis method supports the PKCE flow.", + "text": "- This method is used for signing in using [Social Login (OAuth) providers](/docs/guides/auth#configure-third-party-providers).\n- It works by redirecting your application to the provider's authorization screen, before bringing back the user to your app.", + "examples": [ + { + "id": "sign-in-using-a-third-party-provider", + "name": "Sign in using a third-party provider", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithOAuth({\n provider: 'github'\n})\n```", + "response": "```json\n{\n data: {\n provider: 'github',\n url: \n },\n error: null\n}\n```" + }, + { + "id": "sign-in-using-a-third-party-provider-with-redirect", + "name": "Sign in using a third-party provider with redirect", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithOAuth({\n provider: 'github',\n options: {\n redirectTo: 'https://example.com/welcome'\n }\n})\n```", + "description": "- When the OAuth provider successfully authenticates the user, they are redirected to the URL specified in the `redirectTo` parameter. This parameter defaults to the [`SITE_URL`](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls). It does not redirect the user immediately after invoking this method.\n- See [redirect URLs and wildcards](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls) to add additional redirect URLs to your project." + }, + { + "id": "sign-in-with-scopes-and-access-provider-tokens", + "name": "Sign in with scopes and access provider tokens", + "code": "```js\n// Register this immediately after calling createClient!\n// Because signInWithOAuth causes a redirect, you need to fetch the\n// provider tokens from the callback.\nsupabase.auth.onAuthStateChange((event, session) => {\n if (session && session.provider_token) {\n window.localStorage.setItem('oauth_provider_token', session.provider_token)\n }\n\n if (session && session.provider_refresh_token) {\n window.localStorage.setItem('oauth_provider_refresh_token', session.provider_refresh_token)\n }\n\n if (event === 'SIGNED_OUT') {\n window.localStorage.removeItem('oauth_provider_token')\n window.localStorage.removeItem('oauth_provider_refresh_token')\n }\n})\n\n// Call this on your Sign in with GitHub button to initiate OAuth\n// with GitHub with the requested elevated scopes.\nawait supabase.auth.signInWithOAuth({\n provider: 'github',\n options: {\n scopes: 'repo gist notifications'\n }\n})\n```", + "description": "If you need additional access from an OAuth provider, in order to access provider specific APIs in the name of the user, you can do this by passing in the scopes the user should authorize for your application. Note that the `scopes` option takes in **a space-separated list** of scopes.\n\nBecause OAuth sign-in often includes redirects, you should register an `onAuthStateChange` callback immediately after you create the Supabase client. This callback will listen for the presence of `provider_token` and `provider_refresh_token` properties on the `session` object and store them in local storage. The client library will emit these values **only once** immediately after the user signs in. You can then access them by looking them up in local storage, or send them to your backend servers for further processing.\n\nFinally, make sure you remove them from local storage on the `SIGNED_OUT` event. If the OAuth provider supports token revocation, make sure you call those APIs either from the frontend or schedule them to be called on the backend." + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.signInWithOtp": { + "name": "@supabase/supabase-js.GoTrueClient.signInWithOtp", + "params": [ + { + "name": "credentials", + "type": { + "type": "union", + "name": "SignInWithPasswordlessCredentials", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's email address." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "object" + }, + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.\n\nThe `data` should be a JSON object that includes user-specific info, such as their first and last name." + } + }, + { + "name": "emailRedirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The redirect url embedded in the email link" + } + }, + { + "name": "shouldCreateUser", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If set to false, this method will not create a new user. Defaults to true." + } + } + ] + }, + "isOptional": true + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "channel", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "sms" + }, + { + "type": "literal", + "value": "whatsapp" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Messaging channel to use (e.g. whatsapp or sms)" + } + }, + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "object" + }, + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.\n\nThe `data` should be a JSON object that includes user-specific info, such as their first and last name." + } + }, + { + "name": "shouldCreateUser", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If set to false, this method will not create a new user. Defaults to true." + } + } + ] + }, + "isOptional": true + }, + { + "name": "phone", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's phone number." + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthOtpResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "messageId", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true + }, + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "messageId", + "type": "[Circular]" + }, + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Log in a user using magiclink or a one-time password (OTP).\n\nIf the `{{ .ConfirmationURL }}` variable is specified in the email template, a magiclink will be sent.\nIf the `{{ .Token }}` variable is specified in the email template, an OTP will be sent.\nIf you're using phone sign-ins, only an OTP will be sent. You won't be able to send a magiclink for phone sign-ins.\n\nBe aware that you may get back an error message that will not distinguish\nbetween the cases where the account does not exist or, that the account\ncan only be accessed via social login.\n\nDo note that you will need to configure a Whatsapp sender on Twilio\nif you are using phone sign in with the 'whatsapp' channel. The whatsapp\nchannel is not supported on other providers\nat this time.\nThis method supports PKCE when an email is passed.", + "text": "- Requires either an email or phone number.\n- This method is used for passwordless sign-ins where a OTP is sent to the user's email or phone number.\n- If the user doesn't exist, `signInWithOtp()` will signup the user instead. To restrict this behavior, you can set `shouldCreateUser` in `SignInWithPasswordlessCredentials.options` to `false`.\n- If you're using an email, you can configure whether you want the user to receive a magiclink or a OTP.\n- If you're using phone, you can configure whether you want the user to receive a OTP.\n- The magic link's destination URL is determined by the [`SITE_URL`](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls).\n- See [redirect URLs and wildcards](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls) to add additional redirect URLs to your project.\n- Magic links and OTPs share the same implementation. To send users a one-time code instead of a magic link, [modify the magic link email template](/dashboard/project/_/auth/templates) to include `{{ .Token }}` instead of `{{ .ConfirmationURL }}`.\n- See our [Twilio Phone Auth Guide](/docs/guides/auth/phone-login?showSMSProvider=Twilio) for details about configuring WhatsApp sign in.", + "examples": [ + { + "id": "sign-in-with-email", + "name": "Sign in with email", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithOtp({\n email: 'example@email.com',\n options: {\n emailRedirectTo: 'https://example.com/welcome'\n }\n})\n```", + "description": "The user will be sent an email which contains either a magiclink or a OTP or both. By default, a given user can only request a OTP once every 60 seconds.", + "response": "```json\n{\n \"data\": {\n \"user\": null,\n \"session\": null\n },\n \"error\": null\n}\n```" + }, + { + "id": "sign-in-with-sms-otp", + "name": "Sign in with SMS OTP", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithOtp({\n phone: '+13334445555',\n})\n```", + "description": "The user will be sent a SMS which contains a OTP. By default, a given user can only request a OTP once every 60 seconds." + }, + { + "id": "sign-in-with-whatsapp-otp", + "name": "Sign in with WhatsApp OTP", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithOtp({\n phone: '+13334445555',\n options: {\n channel:'whatsapp',\n }\n})\n```", + "description": "The user will be sent a WhatsApp message which contains a OTP. By default, a given user can only request a OTP once every 60 seconds. Note that a user will need to have a valid WhatsApp account that is linked to Twilio in order to use this feature." + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.signInWithPasskey": { + "name": "@supabase/supabase-js.GoTrueClient.signInWithPasskey", + "params": [ + { + "name": "credentials", + "type": { + "name": "SignInWithPasskeyCredentials", + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyAuthenticationVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + { + "type": "literal", + "value": null + } + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + { + "type": "literal", + "value": null + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Sign in with a passkey. Handles the full WebAuthn ceremony:\n1. Fetches authentication challenge from server\n2. Prompts user via navigator.credentials.get()\n3. Verifies credential with server and creates session\n\nRequires `auth.experimental.passkey: true`." + } + }, + "@supabase/supabase-js.GoTrueClient.signInWithPassword": { + "name": "@supabase/supabase-js.GoTrueClient.signInWithPassword", + "params": [ + { + "name": "credentials", + "type": { + "type": "nameOnly", + "name": "SignInWithPasswordCredentials" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthTokenResponsePassword", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + }, + { + "name": "weakPassword", + "type": { + "name": "WeakPassword", + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "reasons", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "WeakPasswordReasons" + } + } + } + ] + }, + "isOptional": true + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + }, + { + "name": "weakPassword", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Log in an existing user with an email and password or phone and password.\n\nBe aware that you may get back an error message that will not distinguish\nbetween the cases where the account does not exist or that the\nemail/phone and password combination is wrong or that the account can only\nbe accessed via social login.", + "text": "- Requires either an email and password or a phone number and password.", + "examples": [ + { + "id": "sign-in-with-email-and-password", + "name": "Sign in with email and password", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithPassword({\n email: 'example@email.com',\n password: 'example-password',\n})\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {},\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\"\n },\n \"session\": {\n \"access_token\": \"\",\n \"token_type\": \"bearer\",\n \"expires_in\": 3600,\n \"expires_at\": 1700000000,\n \"refresh_token\": \"\",\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {},\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\"\n }\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "sign-in-with-phone-and-password", + "name": "Sign in with phone and password", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithPassword({\n phone: '+13334445555',\n password: 'some-password',\n})\n```" + }, + { + "id": "handling-errors", + "name": "Handling errors", + "code": "```js\nconst { data, error } = await supabase.auth.signInWithPassword({\n email: 'example@email.com',\n password: 'example-password',\n})\nif (error) {\n console.error(error)\n return\n}\n```", + "description": "Log the full `error` object so fields like `code`, `status`, and `name` aren't hidden. The `error.code` (e.g. `'invalid_credentials'`, `'email_not_confirmed'`) is often more useful for branching than `error.message`, and the full object surfaces both." + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.signInWithSSO": { + "name": "@supabase/supabase-js.GoTrueClient.signInWithSSO", + "params": [ + { + "name": "params", + "type": { + "type": "union", + "name": "SignInWithSSO", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "redirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "A URL to send the user to after they have signed-in." + } + }, + { + "name": "skipBrowserRedirect", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If set to true, the redirect will not happen on the client side.\nThis parameter is used when you wish to handle the redirect yourself.\nDefaults to false." + } + } + ] + }, + "isOptional": true + }, + { + "name": "providerId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "UUID of the SSO provider to invoke single-sign on to." + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "domain", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Domain name of the organization for which to invoke single-sign on." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "redirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "A URL to send the user to after they have signed-in." + } + }, + { + "name": "skipBrowserRedirect", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If set to true, the redirect will not happen on the client side.\nThis parameter is used when you wish to handle the redirect yourself.\nDefaults to false." + } + } + ] + }, + "isOptional": true + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "SSOResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "URL to open in a browser which will complete the sign-in flow by\ntaking the user to the identity provider's authentication flow.\n\nOn browsers you can set the URL to `window.location.href` to take\nthe user to the authentication flow." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Attempts a single-sign on using an enterprise Identity Provider. A\nsuccessful SSO attempt will redirect the current page to the identity\nprovider authorization page. The redirect URL is implementation and SSO\nprotocol specific.\n\nYou can use it by providing a SSO domain. Typically you can extract this\ndomain by asking users for their email address. If this domain is\nregistered on the Auth instance the redirect will use that organization's\ncurrently active SSO Identity Provider for the login.\n\nIf you have built an organization-specific login page, you can use the\norganization's SSO Identity Provider UUID directly instead.", + "text": "- Before you can call this method you need to [establish a connection](/docs/guides/auth/sso/auth-sso-saml#managing-saml-20-connections) to an identity provider. Use the [CLI commands](/docs/reference/cli/supabase-sso) to do this.\n- If you've associated an email domain to the identity provider, you can use the `domain` property to start a sign-in flow.\n- In case you need to use a different way to start the authentication flow with an identity provider, you can use the `providerId` property. For example:\n - Mapping specific user email addresses with an identity provider.\n - Using different hints to identity the identity provider to be used by the user, like a company-specific page, IP address or other tracking information.", + "examples": [ + { + "id": "sign-in-with-email-domain", + "name": "Sign in with email domain", + "code": "```js\n // You can extract the user's email domain and use it to trigger the\n // authentication flow with the correct identity provider.\n\n const { data, error } = await supabase.auth.signInWithSSO({\n domain: 'company.com'\n })\n\n if (data?.url) {\n // redirect the user to the identity provider's authentication flow\n window.location.href = data.url\n }\n```" + }, + { + "id": "sign-in-with-provider-uuid", + "name": "Sign in with provider UUID", + "code": "```js\n // Useful when you need to map a user's sign in request according\n // to different rules that can't use email domains.\n\n const { data, error } = await supabase.auth.signInWithSSO({\n providerId: '21648a9d-8d5a-4555-a9d1-d6375dc14e92'\n })\n\n if (data?.url) {\n // redirect the user to the identity provider's authentication flow\n window.location.href = data.url\n }\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.signInWithWeb3": { + "name": "@supabase/supabase-js.GoTrueClient.signInWithWeb3", + "params": [ + { + "name": "credentials", + "type": { + "type": "union", + "name": "Web3Credentials", + "subTypes": [ + { + "type": "union", + "name": "SolanaWeb3Credentials", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "chain", + "type": { + "type": "literal", + "value": "solana" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "signInWithSolana", + "type": { + "type": "nameOnly", + "name": "Partial" + }, + "isOptional": true + }, + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URL to use with the wallet interface. Some wallets do not allow signing a message for URLs different from the current page." + } + } + ] + }, + "isOptional": true + }, + { + "name": "statement", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Optional statement to include in the Sign in with Solana message. Must not include new line characters. Most wallets like Phantom **require specifying a statement!**" + } + }, + { + "name": "wallet", + "type": { + "name": "SolanaWallet", + "type": "object", + "properties": [ + { + "name": "publicKey", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "toBase58", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "string" + } + } + } + } + ] + }, + { + "type": "literal", + "value": null + } + ] + }, + "isOptional": true + }, + { + "name": "signIn", + "type": { + "type": "function", + "params": [ + { + "name": "inputs", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "SolanaSignInInput" + } + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "SolanaSignInOutput" + }, + { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "SolanaSignInOutput" + } + } + ] + } + } + } + }, + "isOptional": true + }, + { + "name": "signMessage", + "type": { + "type": "function", + "params": [ + { + "name": "message", + "type": { + "type": "nameOnly", + "name": "Uint8Array" + } + }, + { + "name": "encoding", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "utf8" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Uint8Array" + } + }, + { + "type": "intrinsic", + "name": "undefined" + } + ] + } + } + }, + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Wallet interface to use. If not specified will default to `window.solana`." + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "chain", + "type": { + "type": "literal", + "value": "solana" + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Sign in with Solana compatible message. Must include `Issued At`, `URI` and `Version`." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + } + ] + }, + "isOptional": true + }, + { + "name": "signature", + "type": { + "type": "nameOnly", + "name": "Uint8Array" + }, + "comment": { + "shortText": "Ed25519 signature of the message." + } + } + ] + } + ] + }, + { + "type": "union", + "name": "EthereumWeb3Credentials", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "chain", + "type": { + "type": "literal", + "value": "ethereum" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "signInWithEthereum", + "type": { + "type": "nameOnly", + "name": "Partial" + }, + "isOptional": true + }, + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URL to use with the wallet interface. Some wallets do not allow signing a message for URLs different from the current page." + } + } + ] + }, + "isOptional": true + }, + { + "name": "statement", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Optional statement to include in the Sign in with Ethereum message. Must not include new line characters. Most wallets like Phantom **require specifying a statement!**" + } + }, + { + "name": "wallet", + "type": { + "type": "nameOnly", + "name": "EthereumWallet" + }, + "isOptional": true, + "comment": { + "shortText": "Wallet interface to use. If not specified will default to `window.ethereum`." + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "chain", + "type": { + "type": "literal", + "value": "ethereum" + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Sign in with Ethereum compatible message. Must include `Issued At`, `URI` and `Version`." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + } + ] + }, + "isOptional": true + }, + { + "name": "signature", + "type": { + "type": "nameOnly", + "name": "Hex" + }, + "comment": { + "shortText": "Ethereum curve (secp256k1) signature of the message." + } + } + ] + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "user", + "type": { + "type": "literal", + "value": null + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Signs in a user by verifying a message signed by the user's private key.\nSupports Ethereum (via Sign-In-With-Ethereum) & Solana (Sign-In-With-Solana) standards,\nboth of which derive from the EIP-4361 standard\nWith slight variation on Solana's side.", + "text": "- Uses a Web3 (Ethereum, Solana) wallet to sign a user in.\n- Read up on the [potential for abuse](/docs/guides/auth/auth-web3#potential-for-abuse) before using it.", + "examples": [ + { + "id": "sign-in-with-solana-or-ethereum-window-api", + "name": "Sign in with Solana or Ethereum (Window API)", + "code": "```js\n // uses window.ethereum for the wallet\n const { data, error } = await supabase.auth.signInWithWeb3({\n chain: 'ethereum',\n statement: 'I accept the Terms of Service at https://example.com/tos'\n })\n\n // uses window.solana for the wallet\n const { data, error } = await supabase.auth.signInWithWeb3({\n chain: 'solana',\n statement: 'I accept the Terms of Service at https://example.com/tos'\n })\n```" + }, + { + "id": "sign-in-with-ethereum-message-and-signature", + "name": "Sign in with Ethereum (Message and Signature)", + "code": "```js\n const { data, error } = await supabase.auth.signInWithWeb3({\n chain: 'ethereum',\n message: '',\n signature: '',\n })\n```" + }, + { + "id": "sign-in-with-solana-brave", + "name": "Sign in with Solana (Brave)", + "code": "```js\n const { data, error } = await supabase.auth.signInWithWeb3({\n chain: 'solana',\n statement: 'I accept the Terms of Service at https://example.com/tos',\n wallet: window.braveSolana\n })\n```" + }, + { + "id": "sign-in-with-solana-wallet-adapter", + "name": "Sign in with Solana (Wallet Adapter)", + "code": "```jsx\n function SignInButton() {\n const wallet = useWallet()\n\n return (\n <>\n {wallet.connected ? (\n {\n supabase.auth.signInWithWeb3({\n chain: 'solana',\n statement: 'I accept the Terms of Service at https://example.com/tos',\n wallet,\n })\n }}\n >\n Sign in with Solana\n \n ) : (\n \n )}\n \n )\n}\n\nfunction App() {\n const endpoint = clusterApiUrl('devnet')\n const wallets = useMemo(() => [], [])\n\n return (\n \n \n \n \n \n \n \n )\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.signOut": { + "name": "@supabase/supabase-js.GoTrueClient.signOut", + "params": [ + { + "name": "options", + "type": { + "name": "SignOut", + "type": "object", + "properties": [ + { + "name": "scope", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "Determines which sessions should be\nlogged out. Global means all\nsessions by this account. Local\nmeans only this session. Others\nmeans all other sessions except the\ncurrent one. When using others,\nthere is no sign-out event fired on\nthe current session!" + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "object", + "properties": [ + { + "name": "error", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "nameOnly", + "name": "AuthError" + } + ] + } + } + ] + } + } + }, + "comment": { + "shortText": "Inside a browser context, `signOut()` will remove the logged in user from the browser session and log them out - removing all items from localstorage and then trigger a `\"SIGNED_OUT\"` event.\n\nFor server-side management, you can revoke all refresh tokens for a user by passing a user's JWT through to `auth.api.signOut(JWT: string)`.\nThere is no way to revoke a user's access token jwt until it expires. It is recommended to set a shorter expiry on the jwt for this reason.\n\nIf using `others` scope, no `SIGNED_OUT` event is fired!\n\n**Warning:** the default `scope` is `'global'`. This signs the user out of\n**every device they are currently signed in on**, not just the current\ntab/session. If you only want to sign the user out of the current session\n(the behavior most other auth libraries default to), pass\n`{ scope: 'local' }` explicitly.", + "text": "- In order to use the `signOut()` method, the user needs to be signed in first.\n- By default, `signOut()` uses the **global** scope, which signs out the user\n on every device they are signed in on (not just the current one). Pass\n `{ scope: 'local' }` to only sign out the current session. This is\n usually what apps want on a \"Sign out\" button, especially when users\n sign in from multiple devices and do not expect signing out of one to\n terminate the others.\n- Since Supabase Auth uses JWTs for authentication, the access token JWT will be valid until it's expired. When the user signs out, Supabase revokes the refresh token and deletes the JWT from the client-side. This does not revoke the JWT and it will still be valid until it expires.", + "examples": [ + { + "id": "sign-out-of-every-device-global-default", + "name": "Sign out of every device (global – default)", + "code": "```js\nconst { error } = await supabase.auth.signOut()\n```" + }, + { + "id": "sign-out-only-the-current-session-recommended-for-most-apps", + "name": "Sign out only the current session (recommended for most apps)", + "code": "```js\nconst { error } = await supabase.auth.signOut({ scope: 'local' })\n```" + }, + { + "id": "sign-out-of-all-other-sessions-keep-the-current-one", + "name": "Sign out of all other sessions, keep the current one", + "code": "```js\nconst { error } = await supabase.auth.signOut({ scope: 'others' })\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.signUp": { + "name": "@supabase/supabase-js.GoTrueClient.signUp", + "params": [ + { + "name": "credentials", + "type": { + "type": "nameOnly", + "name": "SignUpWithPasswordCredentials" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + "[Circular]" + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "[Circular]" + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a new user.\n\nBe aware that if a user account exists in the system you may get back an\nerror message that attempts to hide this information from the user.\nThis method has support for PKCE via email signups. The PKCE flow cannot be used when autoconfirm is enabled.", + "text": "- By default, the user needs to verify their email address before logging in. To turn this off, disable **Confirm email** in [your project](/dashboard/project/_/auth/providers).\n- **Confirm email** determines if users need to confirm their email address after signing up.\n - If **Confirm email** is enabled, a `user` is returned but `session` is null.\n - If **Confirm email** is disabled, both a `user` and a `session` are returned.\n- When the user confirms their email address, they are redirected to the [`SITE_URL`](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls) by default. You can modify your `SITE_URL` or add additional redirect URLs in [your project](/dashboard/project/_/auth/url-configuration).\n- If signUp() is called for an existing confirmed user:\n - When both **Confirm email** and **Confirm phone** (even when phone provider is disabled) are enabled in [your project](/dashboard/project/_/auth/providers), an obfuscated/fake user object is returned.\n - When either **Confirm email** or **Confirm phone** (even when phone provider is disabled) is disabled, the error message, `User already registered` is returned.\n- To fetch the currently logged-in user, refer to [`getUser()`](/docs/reference/javascript/auth-getuser).", + "examples": [ + { + "id": "sign-up-with-an-email-and-password", + "name": "Sign up with an email and password", + "code": "```js\nconst { data, error } = await supabase.auth.signUp({\n email: 'example@email.com',\n password: 'example-password',\n})\n```", + "response": "```json\n// Some fields may be null if \"confirm email\" is enabled.\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {},\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\"\n },\n \"session\": {\n \"access_token\": \"\",\n \"token_type\": \"bearer\",\n \"expires_in\": 3600,\n \"expires_at\": 1700000000,\n \"refresh_token\": \"\",\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {},\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\"\n }\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "sign-up-with-a-phone-number-and-password-sms", + "name": "Sign up with a phone number and password (SMS)", + "code": "```js\nconst { data, error } = await supabase.auth.signUp({\n phone: '123456789',\n password: 'example-password',\n options: {\n channel: 'sms'\n }\n})\n```" + }, + { + "id": "sign-up-with-a-phone-number-and-password-whatsapp", + "name": "Sign up with a phone number and password (whatsapp)", + "code": "```js\nconst { data, error } = await supabase.auth.signUp({\n phone: '123456789',\n password: 'example-password',\n options: {\n channel: 'whatsapp'\n }\n})\n```", + "description": "The user will be sent a WhatsApp message which contains a OTP. By default, a given user can only request a OTP once every 60 seconds. Note that a user will need to have a valid WhatsApp account that is linked to Twilio in order to use this feature." + }, + { + "id": "sign-up-with-additional-user-metadata", + "name": "Sign up with additional user metadata", + "code": "```js\nconst { data, error } = await supabase.auth.signUp(\n {\n email: 'example@email.com',\n password: 'example-password',\n options: {\n data: {\n first_name: 'John',\n age: 27,\n }\n }\n }\n)\n```" + }, + { + "id": "sign-up-with-a-redirect-url", + "name": "Sign up with a redirect URL", + "code": "```js\nconst { data, error } = await supabase.auth.signUp(\n {\n email: 'example@email.com',\n password: 'example-password',\n options: {\n emailRedirectTo: 'https://example.com/welcome'\n }\n }\n)\n```", + "description": "- See [redirect URLs and wildcards](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls) to add additional redirect URLs to your project." + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.startAutoRefresh": { + "name": "@supabase/supabase-js.GoTrueClient.startAutoRefresh", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "Starts an auto-refresh process in the background. The session is checked\nevery few seconds. Close to the time of expiration a process is started to\nrefresh the session. If refreshing fails it will be retried for as long as\nnecessary.\n\nIf you set the GoTrueClientOptions#autoRefreshToken you don't need\nto call this function, it will be called for you.\n\nOn browsers the refresh process works only when the tab/window is in the\nforeground to conserve resources as well as prevent race conditions and\nflooding auth with requests. If you call this method any managed\nvisibility change callback will be removed and you must manage visibility\nchanges on your own.\n\nOn non-browser platforms the refresh process works *continuously* in the\nbackground, which may not be desirable. You should hook into your\nplatform's foreground indication mechanism and call these methods\nappropriately to conserve resources.\n\n#stopAutoRefresh", + "text": "- Only useful in non-browser environments such as React Native or Electron.\n- The Supabase Auth library automatically starts and stops proactively refreshing the session when a tab is focused or not.\n- On non-browser platforms, such as mobile or desktop apps built with web technologies, the library is not able to effectively determine whether the application is _focused_ or not.\n- To give this hint to the application, you should be calling this method when the app is in focus and calling `supabase.auth.stopAutoRefresh()` when it's out of focus.", + "examples": [ + { + "id": "start-and-stop-auto-refresh-in-react-native", + "name": "Start and stop auto refresh in React Native", + "code": "```js\nimport { AppState } from 'react-native'\n\n// make sure you register this only once!\nAppState.addEventListener('change', (state) => {\n if (state === 'active') {\n supabase.auth.startAutoRefresh()\n } else {\n supabase.auth.stopAutoRefresh()\n }\n})\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.stopAutoRefresh": { + "name": "@supabase/supabase-js.GoTrueClient.stopAutoRefresh", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "Stops an active auto refresh process running in the background (if any).\n\nIf you call this method any managed visibility change callback will be\nremoved and you must manage visibility changes on your own.\n\nSee #startAutoRefresh for more details.", + "text": "- Only useful in non-browser environments such as React Native or Electron.\n- The Supabase Auth library automatically starts and stops proactively refreshing the session when a tab is focused or not.\n- On non-browser platforms, such as mobile or desktop apps built with web technologies, the library is not able to effectively determine whether the application is _focused_ or not.\n- When your application goes in the background or out of focus, call this method to stop the proactive refreshing of the session.", + "examples": [ + { + "id": "start-and-stop-auto-refresh-in-react-native", + "name": "Start and stop auto refresh in React Native", + "code": "```js\nimport { AppState } from 'react-native'\n\n// make sure you register this only once!\nAppState.addEventListener('change', (state) => {\n if (state === 'active') {\n supabase.auth.startAutoRefresh()\n } else {\n supabase.auth.stopAutoRefresh()\n }\n})\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.unlinkIdentity": { + "name": "@supabase/supabase-js.GoTrueClient.unlinkIdentity", + "params": [ + { + "name": "identity", + "type": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Unlinks an identity from a user by deleting it. The user will no longer be able to sign in with that identity once it's unlinked.", + "text": "- The **Enable Manual Linking** option must be enabled from your [project's authentication settings](/dashboard/project/_/auth/providers).\n- The user needs to be signed in to call `unlinkIdentity()`.\n- The user must have at least 2 identities in order to unlink an identity.\n- The identity to be unlinked must belong to the user.", + "examples": [ + { + "id": "unlink-an-identity", + "name": "Unlink an identity", + "code": "```js\n// retrieve all identities linked to a user\nconst identities = await supabase.auth.getUserIdentities()\n\n// find the google identity\nconst googleIdentity = identities.find(\n identity => identity.provider === 'google'\n)\n\n// unlink the google identity\nconst { error } = await supabase.auth.unlinkIdentity(googleIdentity)\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.updateUser": { + "name": "@supabase/supabase-js.GoTrueClient.updateUser", + "params": [ + { + "name": "attributes", + "type": { + "type": "object", + "name": "UserAttributes", + "properties": [ + { + "name": "current_password", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The user's current password\n\nThis is only ever present when the user is resetting\ntheir password and GOTRUE_SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD is true." + } + }, + { + "name": "data", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.\n\nThe `data` should be a JSON object that includes user-specific info, such as their first and last name." + } + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The user's email." + } + }, + { + "name": "nonce", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The nonce sent for reauthentication if the user's password is to be updated.\n\nCall reauthenticate() to obtain the nonce first." + } + }, + { + "name": "password", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The user's password." + } + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The user's phone." + } + } + ] + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "emailRedirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "UserResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Updates user data for a logged in user.", + "text": "- In order to use the `updateUser()` method, the user needs to be signed in first.\n- By default, email updates sends a confirmation link to both the user's current and new email.\nTo only send a confirmation link to the user's new email, disable **Secure email change** in your project's [email auth provider settings](/dashboard/project/_/auth/providers).", + "examples": [ + { + "id": "update-the-email-for-an-authenticated-user", + "name": "Update the email for an authenticated user", + "code": "```js\nconst { data, error } = await supabase.auth.updateUser({\n email: 'new@email.com'\n})\n```", + "description": "Sends a \"Confirm Email Change\" email to the new address. If **Secure Email Change** is enabled (default), confirmation is also required from the **old email** before the change is applied. To skip dual confirmation and apply the change after only the new email is verified, disable **Secure Email Change** in the [Email Auth Provider settings](/dashboard/project/_/auth/providers?provider=Email).", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"new_email\": \"new@email.com\",\n \"email_change_sent_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "update-the-phone-number-for-an-authenticated-user", + "name": "Update the phone number for an authenticated user", + "code": "```js\nconst { data, error } = await supabase.auth.updateUser({\n phone: '123456789'\n})\n```", + "description": "Sends a one-time password (OTP) to the new phone number." + }, + { + "id": "update-the-password-for-an-authenticated-user", + "name": "Update the password for an authenticated user", + "code": "```js\nconst { data, error } = await supabase.auth.updateUser({\n password: 'new password'\n})\n```" + }, + { + "id": "update-the-user-s-metadata", + "name": "Update the user's metadata", + "code": "```js\nconst { data, error } = await supabase.auth.updateUser({\n data: { hello: 'world' }\n})\n```", + "description": "Updates the user's custom metadata.\n\n**Note**: The `data` field maps to the `auth.users.raw_user_meta_data` column in your Supabase database. When calling `getUser()`, the data will be available as `user.user_metadata`." + }, + { + "id": "update-the-user-s-password-with-a-nonce", + "name": "Update the user's password with a nonce", + "code": "```js\nconst { data, error } = await supabase.auth.updateUser({\n password: 'new password',\n nonce: '123456'\n})\n```", + "description": "If **Secure password change** is enabled in your [project's email provider settings](/dashboard/project/_/auth/providers), updating the user's password would require a nonce if the user **hasn't recently signed in**. The nonce is sent to the user's email or phone number. A user is deemed recently signed in if the session was created in the last 24 hours." + } + ] + } + }, + "@supabase/supabase-js.GoTrueClient.verifyOtp": { + "name": "@supabase/supabase-js.GoTrueClient.verifyOtp", + "params": [ + { + "name": "params", + "type": { + "type": "union", + "name": "VerifyOtpParams", + "subTypes": [ + { + "type": "object", + "name": "VerifyMobileOtpParams", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "redirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "A URL to send the user to after they are confirmed." + } + } + ] + }, + "isOptional": true + }, + { + "name": "phone", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's phone number." + } + }, + { + "name": "token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The otp sent to the user's phone number." + } + }, + { + "name": "type", + "type": { + "type": "union", + "name": "MobileOtpType", + "subTypes": [ + { + "type": "literal", + "value": "sms" + }, + { + "type": "literal", + "value": "phone_change" + }, + null + ] + }, + "comment": { + "shortText": "The user's verification type." + } + } + ] + }, + { + "type": "object", + "name": "VerifyEmailOtpParams", + "properties": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The user's email address." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Verification token received when the user completes the captcha on the site." + } + }, + { + "name": "redirectTo", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "A URL to send the user to after they are confirmed." + } + } + ] + }, + "isOptional": true + }, + { + "name": "token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The otp sent to the user's email address." + } + }, + { + "name": "type", + "type": { + "type": "union", + "name": "EmailOtpType", + "subTypes": [ + { + "type": "literal", + "value": "signup" + }, + { + "type": "literal", + "value": "invite" + }, + { + "type": "literal", + "value": "magiclink" + }, + { + "type": "literal", + "value": "recovery" + }, + { + "type": "literal", + "value": "email_change" + }, + { + "type": "literal", + "value": "email" + }, + null + ] + }, + "comment": { + "shortText": "The user's verification type." + } + } + ] + }, + { + "type": "object", + "name": "VerifyTokenHashParams", + "properties": [ + { + "name": "token_hash", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The token hash used in an email link" + } + }, + { + "name": "type", + "type": { + "type": "union", + "name": "EmailOtpType", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + }, + "comment": { + "shortText": "The user's verification type." + } + } + ] + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + "[Circular]" + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "[Circular]" + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": "[Circular]" + }, + { + "name": "user", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Log in a user given a User supplied OTP or TokenHash received through mobile or email.", + "text": "- The `verifyOtp` method takes in different verification types.\n- If a phone number is used, the type can either be:\n 1. `sms` – Used when verifying a one-time password (OTP) sent via SMS during sign-up or sign-in.\n 2. `phone_change` – Used when verifying an OTP sent to a new phone number during a phone number update process.\n- If an email address is used, the type can be one of the following (note: `signup` and `magiclink` types are deprecated):\n 1. `email` – Used when verifying an OTP sent to the user's email during sign-up or sign-in.\n 2. `recovery` – Used when verifying an OTP sent for account recovery, typically after a password reset request.\n 3. `invite` – Used when verifying an OTP sent as part of an invitation to join a project or organization.\n 4. `email_change` – Used when verifying an OTP sent to a new email address during an email update process.\n- The verification type used should be determined based on the corresponding auth method called before `verifyOtp` to sign up / sign-in a user.\n- The `TokenHash` is contained in the [email templates](/docs/guides/auth/auth-email-templates) and can be used to sign in. You may wish to use the hash for the PKCE flow for Server Side Auth. Read [the Password-based Auth guide](/docs/guides/auth/passwords) for more details.", + "examples": [ + { + "id": "verify-signup-one-time-password-otp", + "name": "Verify Signup One-Time Password (OTP)", + "code": "```js\nconst { data, error } = await supabase.auth.verifyOtp({ email, token, type: 'email'})\n```", + "response": "```json\n{\n \"data\": {\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"recovery_sent_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n },\n \"session\": {\n \"access_token\": \"\",\n \"token_type\": \"bearer\",\n \"expires_in\": 3600,\n \"expires_at\": 1700000000,\n \"refresh_token\": \"\",\n \"user\": {\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"aud\": \"authenticated\",\n \"role\": \"authenticated\",\n \"email\": \"example@email.com\",\n \"email_confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"phone\": \"\",\n \"confirmed_at\": \"2024-01-01T00:00:00Z\",\n \"recovery_sent_at\": \"2024-01-01T00:00:00Z\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"app_metadata\": {\n \"provider\": \"email\",\n \"providers\": [\n \"email\"\n ]\n },\n \"user_metadata\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"identities\": [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": false,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"example@email.com\"\n }\n ],\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"is_anonymous\": false\n }\n }\n },\n \"error\": null\n}\n```" + }, + { + "id": "verify-sms-one-time-password-otp", + "name": "Verify SMS One-Time Password (OTP)", + "code": "```js\nconst { data, error } = await supabase.auth.verifyOtp({ phone, token, type: 'sms'})\n```" + }, + { + "id": "verify-email-auth-token-hash", + "name": "Verify Email Auth (Token Hash)", + "code": "```js\nconst { data, error } = await supabase.auth.verifyOtp({ token_hash: tokenHash, type: 'email'})\n```" + } + ] + } + }, + "@supabase/supabase-js.NavigatorLockAcquireTimeoutError.constructor": { + "name": "@supabase/supabase-js.NavigatorLockAcquireTimeoutError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "NavigatorLockAcquireTimeoutError" + } + } + }, + "@supabase/supabase-js.PostgrestBuilder.constructor": { + "name": "@supabase/supabase-js.PostgrestBuilder.constructor", + "params": [ + { + "name": "builder", + "type": { + "type": "object", + "properties": [ + { + "name": "body", + "type": { + "type": "intrinsic", + "name": "unknown" + }, + "isOptional": true + }, + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RequestInfo" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true + }, + { + "name": "headers", + "type": { + "type": "nameOnly", + "name": "HeadersInit" + } + }, + { + "name": "isMaybeSingle", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "method", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "GET" + }, + { + "type": "literal", + "value": "POST" + }, + { + "type": "literal", + "value": "PATCH" + }, + { + "type": "literal", + "value": "DELETE" + }, + { + "type": "literal", + "value": "HEAD" + } + ] + } + }, + { + "name": "retry", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "schema", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "shouldStripNulls", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "shouldThrowOnError", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "isOptional": true + }, + { + "name": "url", + "type": { + "type": "nameOnly", + "name": "URL" + } + }, + { + "name": "urlLengthLimit", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Creates a builder configured for a specific PostgREST request.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst { data, error } = await supabase.from('users').select('*')\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport { PostgrestQueryBuilder } from '@supabase/postgrest-js'\n\nconst builder = new PostgrestQueryBuilder(\n new URL('https://xyzcompany.supabase.co/rest/v1/users'),\n { headers: new Headers({ apikey: 'your-publishable-key' }) }\n)\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestBuilder.overrideTypes": { + "name": "@supabase/supabase-js.PostgrestBuilder.overrideTypes", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Override the type of the returned `data` field in the response.", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```typescript\n// Merge with existing types (default behavior)\nconst query = supabase\n .from('users')\n .select()\n .overrideTypes<{ custom_field: string }>()\n\n// Replace existing types completely\nconst replaceQuery = supabase\n .from('users')\n .select()\n .overrideTypes<{ id: number; name: string }, { merge: false }>()\n```" + }, + { + "id": "complete-override-type-of-successful-response", + "name": "Complete Override type of successful response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .overrideTypes, { merge: false }>()\n```", + "response": "```ts\nlet x: typeof data // MyType[]\n```" + }, + { + "id": "complete-override-type-of-object-response", + "name": "Complete Override type of object response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .maybeSingle()\n .overrideTypes()\n```", + "response": "```ts\nlet x: typeof data // MyType | null\n```" + }, + { + "id": "partial-override-type-of-successful-response", + "name": "Partial Override type of successful response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .overrideTypes>()\n```", + "response": "```ts\nlet x: typeof data // Array\n```" + }, + { + "id": "partial-override-type-of-object-response", + "name": "Partial Override type of object response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .maybeSingle()\n .overrideTypes<{ status: \"A\" | \"B\" }>()\n```", + "response": "```ts\nlet x: typeof data // CountryRowProperties & { status: \"A\" | \"B\" } | null\n```" + }, + { + "id": "merge-vs-replace-existing-types", + "name": "Merge vs replace existing types", + "code": "```typescript\n// Merge with existing types (default behavior)\nconst query = supabase\n .from('users')\n .select()\n .overrideTypes<{ custom_field: string }>()\n\n// Replace existing types completely\nconst replaceQuery = supabase\n .from('users')\n .select()\n .overrideTypes<{ id: number; name: string }, { merge: false }>()\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestBuilder.retry": { + "name": "@supabase/supabase-js.PostgrestBuilder.retry", + "params": [ + { + "name": "enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "comment": { + "shortText": "Whether to enable retries for this request" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\n// Disable retries for a specific query\nconst { data, error } = await supabase\n .from('users')\n .select()\n .retry(false)\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestBuilder.returns": { + "name": "@supabase/supabase-js.PostgrestBuilder.returns", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Override the type of the returned `data`." + } + }, + "@supabase/supabase-js.PostgrestBuilder.setHeader": { + "name": "@supabase/supabase-js.PostgrestBuilder.setHeader", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set an HTTP header for the request." + } + }, + "@supabase/supabase-js.PostgrestBuilder.stripNulls": { + "name": "@supabase/supabase-js.PostgrestBuilder.stripNulls", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Strip null values from the response data. Properties with `null` values\nwill be omitted from the returned JSON objects.\n\nRequires PostgREST 11.2.0+.\n\nhttps://docs.postgrest.org/en/stable/references/api/resource_representation.html#stripped-nulls", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .stripNulls()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text, bio text);\n\ninsert into\n characters (id, name, bio)\nvalues\n (1, 'Luke', null),\n (2, 'Leia', 'Princess of Alderaan');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Luke\"\n },\n {\n \"id\": 2,\n \"name\": \"Leia\",\n \"bio\": \"Princess of Alderaan\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestBuilder.then": { + "name": "@supabase/supabase-js.PostgrestBuilder.then", + "params": [ + { + "name": "onfulfilled", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "value" + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult1" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is resolved." + } + }, + { + "name": "onrejected", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "reason", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult2" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is rejected." + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PromiseLike" + } + }, + "comment": { + "shortText": "Attaches callbacks for the resolution and/or rejection of the Promise." + } + }, + "@supabase/supabase-js.PostgrestBuilder.throwOnError": { + "name": "@supabase/supabase-js.PostgrestBuilder.throwOnError", + "params": [], + "comment": { + "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.\n\nhttps://github.com/supabase/supabase-js/issues/92" + } + }, + "@supabase/supabase-js.PostgrestError.constructor": { + "name": "@supabase/supabase-js.PostgrestError.constructor", + "params": [ + { + "name": "context", + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "details", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "hint", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestError" + } + }, + "comment": { + "shortText": "", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\nimport PostgrestError from '@supabase/postgrest-js'\n\nthrow new PostgrestError({\n message: 'Row level security prevented the request',\n details: 'RLS denied the insert',\n hint: 'Check your policies',\n code: 'PGRST301',\n})\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestError.toJSON": { + "name": "@supabase/supabase-js.PostgrestError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "details", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "hint", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.constructor": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.constructor", + "params": [ + { + "name": "builder", + "type": { + "type": "object", + "properties": [ + { + "name": "body", + "type": { + "type": "intrinsic", + "name": "unknown" + }, + "isOptional": true + }, + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RequestInfo" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true + }, + { + "name": "headers", + "type": { + "type": "nameOnly", + "name": "HeadersInit" + } + }, + { + "name": "isMaybeSingle", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "method", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "GET" + }, + { + "type": "literal", + "value": "POST" + }, + { + "type": "literal", + "value": "PATCH" + }, + { + "type": "literal", + "value": "DELETE" + }, + { + "type": "literal", + "value": "HEAD" + } + ] + } + }, + { + "name": "retry", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "schema", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "shouldStripNulls", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "shouldThrowOnError", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "isOptional": true + }, + { + "name": "url", + "type": { + "type": "nameOnly", + "name": "URL" + } + }, + { + "name": "urlLengthLimit", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Creates a builder configured for a specific PostgREST request.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst { data, error } = await supabase.from('users').select('*')\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport { PostgrestQueryBuilder } from '@supabase/postgrest-js'\n\nconst builder = new PostgrestQueryBuilder(\n new URL('https://xyzcompany.supabase.co/rest/v1/users'),\n { headers: new Headers({ apikey: 'your-publishable-key' }) }\n)\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.abortSignal": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.abortSignal", + "params": [ + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "comment": { + "shortText": "The AbortSignal to use for the fetch request" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set the AbortSignal for the fetch request.", + "text": "You can use this to set a timeout for the request.", + "examples": [ + { + "id": "aborting-requests-in-flight", + "name": "Aborting requests in-flight", + "code": "```ts\nconst ac = new AbortController()\n\nconst { data, error } = await supabase\n .from('very_big_table')\n .select()\n .abortSignal(ac.signal)\n\n// Abort the request after 100 ms\nsetTimeout(() => ac.abort(), 100)\n```", + "description": "You can use an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) to abort requests.\nNote that `status` and `statusText` don't mean anything for aborted requests as the request wasn't fulfilled.", + "response": "```json\n {\n \"error\": {\n \"message\": \"AbortError: The user aborted a request.\",\n \"details\": \"\",\n \"hint\": \"The request was aborted locally via the provided AbortSignal.\",\n \"code\": \"\"\n },\n \"status\": 0,\n \"statusText\": \"\"\n }\n\n```" + }, + { + "id": "set-a-timeout", + "name": "Set a timeout", + "code": "```ts\nconst { data, error } = await supabase\n .from('very_big_table')\n .select()\n .abortSignal(AbortSignal.timeout(1000 /* ms */))\n```", + "response": "```json\n {\n \"error\": {\n \"message\": \"FetchError: The user aborted a request.\",\n \"details\": \"\",\n \"hint\": \"\",\n \"code\": \"\"\n },\n \"status\": 400,\n \"statusText\": \"Bad Request\"\n }\n\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.containedBy": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.containedBy", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "value", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "unknown" + } + }, + { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "unknown" + } + }, + { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.contains": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.contains", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "value", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "unknown" + } + }, + { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "unknown" + } + }, + { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.csv": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.csv", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Return `data` as a string in CSV format.", + "examples": [ + { + "id": "return-data-as-csv", + "name": "Return data as CSV", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .csv()\n```", + "description": "By default, the data is returned in JSON format, but can also be returned as Comma Separated Values.", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": \"id,name\\n1,Luke\\n2,Leia\\n3,Han\",\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.eq": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.eq", + "params": [ + { + "name": "column", + "comment": { + "shortText": "The column to filter on" + } + }, + { + "name": "value", + "comment": { + "shortText": "The value to filter with" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` is equal to `value`.\n\nTo check if the value of `column` is NULL, you should use `.is()` instead.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .eq('name', 'Leia')\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 2,\n \"name\": \"Leia\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.explain": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.explain", + "params": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "analyze", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, the query will be executed and the\nactual run time will be returned" + } + }, + { + "name": "buffers", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, include information on buffer usage" + } + }, + { + "name": "format", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "text" + }, + { + "type": "literal", + "value": "json" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The format of the output, can be `\"text\"` (default)\nor `\"json\"`" + } + }, + { + "name": "settings", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, include information on configuration\nparameters that affect query planning" + } + }, + { + "name": "verbose", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, the query identifier will be returned\nand `data` will include the output columns of the query" + } + }, + { + "name": "wal", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, include information on WAL record generation" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "PostgrestBuilder" + }, + { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + ] + } + }, + "comment": { + "shortText": "Return `data` as the EXPLAIN plan for the query.\n\nYou need to enable the\n[db_plan_enabled](https://supabase.com/docs/guides/database/debugging-performance#enabling-explain)\nsetting before using this method.", + "examples": [ + { + "id": "get-the-execution-plan", + "name": "Get the execution plan", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .explain()\n```", + "description": "By default, the data is returned in TEXT format, but can also be returned as JSON by using the `format` parameter.", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```js\nAggregate (cost=33.34..33.36 rows=1 width=112)\n -> Limit (cost=0.00..18.33 rows=1000 width=40)\n -> Seq Scan on characters (cost=0.00..22.00 rows=1200 width=40)\n```" + }, + { + "id": "get-the-execution-plan-with-analyze-and-verbose", + "name": "Get the execution plan with analyze and verbose", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .explain({analyze:true,verbose:true})\n```", + "description": "By default, the data is returned in TEXT format, but can also be returned as JSON by using the `format` parameter.", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```js\nAggregate (cost=33.34..33.36 rows=1 width=112) (actual time=0.041..0.041 rows=1 loops=1)\n Output: NULL::bigint, count(ROW(characters.id, characters.name)), COALESCE(json_agg(ROW(characters.id, characters.name)), '[]'::json), NULLIF(current_setting('response.headers'::text, true), ''::text), NULLIF(current_setting('response.status'::text, true), ''::text)\n -> Limit (cost=0.00..18.33 rows=1000 width=40) (actual time=0.005..0.006 rows=3 loops=1)\n Output: characters.id, characters.name\n -> Seq Scan on public.characters (cost=0.00..22.00 rows=1200 width=40) (actual time=0.004..0.005 rows=3 loops=1)\n Output: characters.id, characters.name\nQuery Identifier: -4730654291623321173\nPlanning Time: 0.407 ms\nExecution Time: 0.119 ms\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.filter": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.filter", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "operator", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "FilterOperator" + }, + { + "type": "literal", + "value": "not.match" + }, + { + "type": "literal", + "value": "not.eq" + }, + { + "type": "literal", + "value": "not.neq" + }, + { + "type": "literal", + "value": "not.gt" + }, + { + "type": "literal", + "value": "not.gte" + }, + { + "type": "literal", + "value": "not.lt" + }, + { + "type": "literal", + "value": "not.lte" + }, + { + "type": "literal", + "value": "not.like" + }, + { + "type": "literal", + "value": "not.ilike" + }, + { + "type": "literal", + "value": "not.is" + }, + { + "type": "literal", + "value": "not.isdistinct" + }, + { + "type": "literal", + "value": "not.in" + }, + { + "type": "literal", + "value": "not.cs" + }, + { + "type": "literal", + "value": "not.cd" + }, + { + "type": "literal", + "value": "not.sl" + }, + { + "type": "literal", + "value": "not.sr" + }, + { + "type": "literal", + "value": "not.nxl" + }, + { + "type": "literal", + "value": "not.nxr" + }, + { + "type": "literal", + "value": "not.adj" + }, + { + "type": "literal", + "value": "not.ov" + }, + { + "type": "literal", + "value": "not.fts" + }, + { + "type": "literal", + "value": "not.plfts" + }, + { + "type": "literal", + "value": "not.phfts" + }, + { + "type": "literal", + "value": "not.wfts" + }, + { + "type": "literal", + "value": "not.imatch" + } + ] + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "operator", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.geojson": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.geojson", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Return `data` as an object in [GeoJSON](https://geojson.org) format." + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.gt": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.gt", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "value", + "type": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.gte": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.gte", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "value", + "type": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.ilike": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.ilike", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "pattern", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "pattern", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.ilikeAllOf": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.ilikeAllOf", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "patterns", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "patterns", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.ilikeAnyOf": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.ilikeAnyOf", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "patterns", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "patterns", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.in": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.in", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + }, + "comment": { + "shortText": "The column to filter on" + } + }, + { + "name": "values", + "type": { + "type": "array" + }, + "comment": { + "shortText": "The values array to filter with" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` is included in the `values` array.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .in('name', ['Leia', 'Han'])\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 2,\n \"name\": \"Leia\"\n },\n {\n \"id\": 3,\n \"name\": \"Han\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.is": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.is", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "value" + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "boolean" + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.isDistinct": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.isDistinct", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + }, + "comment": { + "shortText": "The column to filter on" + } + }, + { + "name": "value", + "comment": { + "shortText": "The value to filter with" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` IS DISTINCT FROM `value`.\n\nUnlike `.neq()`, this treats `NULL` as a comparable value. Two `NULL` values\nare considered equal (not distinct), and comparing `NULL` with any non-NULL\nvalue returns true (distinct)." + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.like": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.like", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "pattern", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "pattern", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.likeAllOf": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.likeAllOf", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "patterns", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "patterns", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.likeAnyOf": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.likeAnyOf", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "patterns", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "patterns", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.limit": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.limit", + "params": [ + { + "name": "rows", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The maximum number of rows to return" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Deprecated, use `options.referencedTable`\ninstead" + } + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Set this to limit rows of referenced\ntables instead of the parent table" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Limit the query result by `rows`.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .limit(1)\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Luke\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "on-a-referenced-table", + "name": "On a referenced table", + "code": "```ts\nconst { data, error } = await supabase\n .from('orchestral_sections')\n .select(`\n name,\n instruments (\n name\n )\n `)\n .limit(1, { referencedTable: 'instruments' })\n```", + "data": { + "sql": "```sql\ncreate table\n orchestral_sections (id int8 primary key, name text);\ncreate table\n instruments (\n id int8 primary key,\n section_id int8 not null references orchestral_sections,\n name text\n );\n\ninsert into\n orchestral_sections (id, name)\nvalues\n (1, 'strings');\ninsert into\n instruments (id, section_id, name)\nvalues\n (1, 1, 'harp'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"strings\",\n \"instruments\": [\n {\n \"name\": \"violin\"\n }\n ]\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.lt": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.lt", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "value", + "type": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.lte": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.lte", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "value", + "type": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.match": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.match", + "params": [ + { + "name": "query", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "nameOnly", + "name": "ColumnName" + }, + "valueType": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "query", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "unknown" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.maxAffected": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.maxAffected", + "params": [ + { + "name": "rows", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The maximum number of rows that can be affected" + } + } + ], + "comment": { + "shortText": "Set the maximum number of rows that can be affected by the query.\nOnly available in PostgREST v13+ and only works with PATCH and DELETE methods." + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.maybeSingle": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.maybeSingle", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Return `data` as a single object instead of an array of objects.\n\nQuery result must be zero or one row (e.g. using `.limit(1)`), otherwise\nthis returns an error.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .eq('name', 'Katniss')\n .maybeSingle()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.neq": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.neq", + "params": [ + { + "name": "column", + "comment": { + "shortText": "The column to filter on" + } + }, + { + "name": "value", + "comment": { + "shortText": "The value to filter with" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` is not equal to `value`.\n\nThis filter does not include rows where `column` is `NULL`. To match null\nvalues, use `.is(column, null)` instead.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .neq('name', 'Leia')\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Luke\"\n },\n {\n \"id\": 3,\n \"name\": \"Han\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.not": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.not", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "operator", + "type": { + "type": "literal", + "value": "is" + } + }, + { + "name": "value", + "type": { + "type": "literal", + "value": null + } + } + ], + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "operator", + "type": { + "type": "nameOnly", + "name": "FilterOperator" + } + }, + { + "name": "value", + "type": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + }, + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "operator", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.notIn": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.notIn", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + }, + "comment": { + "shortText": "The column to filter on" + } + }, + { + "name": "values", + "type": { + "type": "array" + }, + "comment": { + "shortText": "The values array to filter with" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows where `column` is NOT included in the `values` array." + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.or": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.or", + "params": [ + { + "name": "filters", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The filters to use, following PostgREST syntax" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Deprecated, use `referencedTable` instead" + } + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Set this to filter on referenced tables\ninstead of the parent table" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Match only rows which satisfy at least one of the filters.\n\nUnlike most filters, `filters` is used as-is and needs to follow [PostgREST\nsyntax](https://postgrest.org/en/stable/api.html#operators). You also need\nto make sure it's properly sanitized.\n\nIt's currently not possible to do an `.or()` filter across multiple tables.", + "text": "or() expects you to use the raw PostgREST syntax for the filter names and values.\n\n```ts\n.or('id.in.(5,6,7), arraycol.cs.{\"a\",\"b\"}') // Use `()` for `in` filter, `{}` for array values and `cs` for `contains()`.\n.or('id.in.(5,6,7), arraycol.cd.{\"a\",\"b\"}') // Use `cd` for `containedBy()`\n```", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .or('id.eq.2,name.eq.Han')\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Leia\"\n },\n {\n \"name\": \"Han\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "use-or-with-and", + "name": "Use `or` with `and`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .or('id.gt.3,and(id.eq.1,name.eq.Luke)')\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Luke\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "use-or-on-referenced-tables", + "name": "Use `or` on referenced tables", + "code": "```ts\nconst { data, error } = await supabase\n .from('orchestral_sections')\n .select(`\n name,\n instruments!inner (\n name\n )\n `)\n .or('section_id.eq.1,name.eq.guzheng', { referencedTable: 'instruments' })\n```", + "data": { + "sql": "```sql\ncreate table\n orchestral_sections (id int8 primary key, name text);\ncreate table\n instruments (\n id int8 primary key,\n section_id int8 not null references orchestral_sections,\n name text\n );\n\ninsert into\n orchestral_sections (id, name)\nvalues\n (1, 'strings'),\n (2, 'woodwinds');\ninsert into\n instruments (id, section_id, name)\nvalues\n (1, 2, 'flute'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"strings\",\n \"instruments\": [\n {\n \"name\": \"violin\"\n }\n ]\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.order": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.order", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "ascending", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "nullsFirst", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "undefined" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "ascending", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "nullsFirst", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + }, + { + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "ascending", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "undefined" + }, + "isOptional": true + }, + { + "name": "nullsFirst", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + }, + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "ascending", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "nullsFirst", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.overlaps": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.overlaps", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "value", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Row['ColumnName']" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.overrideTypes": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.overrideTypes", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Override the type of the returned `data` field in the response.", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```typescript\n// Merge with existing types (default behavior)\nconst query = supabase\n .from('users')\n .select()\n .overrideTypes<{ custom_field: string }>()\n\n// Replace existing types completely\nconst replaceQuery = supabase\n .from('users')\n .select()\n .overrideTypes<{ id: number; name: string }, { merge: false }>()\n```" + }, + { + "id": "complete-override-type-of-successful-response", + "name": "Complete Override type of successful response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .overrideTypes, { merge: false }>()\n```", + "response": "```ts\nlet x: typeof data // MyType[]\n```" + }, + { + "id": "complete-override-type-of-object-response", + "name": "Complete Override type of object response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .maybeSingle()\n .overrideTypes()\n```", + "response": "```ts\nlet x: typeof data // MyType | null\n```" + }, + { + "id": "partial-override-type-of-successful-response", + "name": "Partial Override type of successful response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .overrideTypes>()\n```", + "response": "```ts\nlet x: typeof data // Array\n```" + }, + { + "id": "partial-override-type-of-object-response", + "name": "Partial Override type of object response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .maybeSingle()\n .overrideTypes<{ status: \"A\" | \"B\" }>()\n```", + "response": "```ts\nlet x: typeof data // CountryRowProperties & { status: \"A\" | \"B\" } | null\n```" + }, + { + "id": "merge-vs-replace-existing-types", + "name": "Merge vs replace existing types", + "code": "```typescript\n// Merge with existing types (default behavior)\nconst query = supabase\n .from('users')\n .select()\n .overrideTypes<{ custom_field: string }>()\n\n// Replace existing types completely\nconst replaceQuery = supabase\n .from('users')\n .select()\n .overrideTypes<{ id: number; name: string }, { merge: false }>()\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.range": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.range", + "params": [ + { + "name": "from", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The starting index from which to limit the result" + } + }, + { + "name": "to", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The last index to which to limit the result" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Deprecated, use `options.referencedTable`\ninstead" + } + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Set this to limit rows of referenced\ntables instead of the parent table" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Limit the query result by starting at an offset `from` and ending at the offset `to`.\nOnly records within this range are returned.\nThis respects the query order and if there is no order clause the range could behave unexpectedly.\nThe `from` and `to` values are 0-based and inclusive: `range(1, 3)` will include the second, third\nand fourth rows of the query.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .range(0, 1)\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Luke\"\n },\n {\n \"name\": \"Leia\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.rangeAdjacent": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.rangeAdjacent", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.rangeGt": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.rangeGt", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.rangeGte": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.rangeGte", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.rangeLt": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.rangeLt", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.rangeLte": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.rangeLte", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "range", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.regexIMatch": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.regexIMatch", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "pattern", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "pattern", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.regexMatch": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.regexMatch", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "pattern", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "pattern", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.retry": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.retry", + "params": [ + { + "name": "enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "comment": { + "shortText": "Whether to enable retries for this request" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\n// Disable retries for a specific query\nconst { data, error } = await supabase\n .from('users')\n .select()\n .retry(false)\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.returns": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.returns", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestTransformBuilder" + } + }, + "comment": { + "shortText": "Override the type of the returned `data`.", + "text": "- Deprecated: use overrideTypes method instead", + "examples": [ + { + "id": "override-type-of-successful-response", + "name": "Override type of successful response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .returns>()\n```", + "response": "```js\nlet x: typeof data // MyType[]\n```" + }, + { + "id": "override-type-of-object-response", + "name": "Override type of object response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .maybeSingle()\n .returns()\n```", + "response": "```js\nlet x: typeof data // MyType | null\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.rollback": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.rollback", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Rollback the query.\n\n`data` will still be returned, but the query is not committed." + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.select": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.select", + "params": [ + { + "name": "columns", + "type": { + "type": "nameOnly", + "name": "Query" + }, + "isOptional": true, + "comment": { + "shortText": "The columns to retrieve, separated by commas" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Perform a SELECT on the query result.\n\nBy default, `.insert()`, `.update()`, `.upsert()`, and `.delete()` do not\nreturn modified rows. By calling this method, modified rows are returned in\n`data`.", + "examples": [ + { + "id": "with-upsert", + "name": "With `upsert()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .upsert({ id: 1, name: 'Han Solo' })\n .select()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Han Solo\"\n }\n ],\n \"status\": 201,\n \"statusText\": \"Created\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.setHeader": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.setHeader", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set an HTTP header for the request." + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.single": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.single", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Return `data` as a single object instead of an array of objects.\n\nQuery result must be one row (e.g. using `.limit(1)`), otherwise this\nreturns an error.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .limit(1)\n .single()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": {\n \"name\": \"Luke\"\n },\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.stripNulls": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.stripNulls", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Strip null values from the response data. Properties with `null` values\nwill be omitted from the returned JSON objects.\n\nRequires PostgREST 11.2.0+.\n\nhttps://docs.postgrest.org/en/stable/references/api/resource_representation.html#stripped-nulls", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .stripNulls()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text, bio text);\n\ninsert into\n characters (id, name, bio)\nvalues\n (1, 'Luke', null),\n (2, 'Leia', 'Princess of Alderaan');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Luke\"\n },\n {\n \"id\": 2,\n \"name\": \"Leia\",\n \"bio\": \"Princess of Alderaan\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.textSearch": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.textSearch", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "query", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "config", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "plain" + }, + { + "type": "literal", + "value": "phrase" + }, + { + "type": "literal", + "value": "websearch" + } + ] + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "query", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "config", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "plain" + }, + { + "type": "literal", + "value": "phrase" + }, + { + "type": "literal", + "value": "websearch" + } + ] + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestFilterBuilder.then": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.then", + "params": [ + { + "name": "onfulfilled", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "value", + "type": { + "type": "union", + "name": "PostgrestSingleResponse", + "subTypes": [ + { + "type": "nameOnly", + "name": "PostgrestResponseSuccess" + }, + { + "type": "nameOnly", + "name": "PostgrestResponseFailure" + } + ] + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult1" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is resolved." + } + }, + { + "name": "onrejected", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "reason", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult2" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is rejected." + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PromiseLike" + } + }, + "comment": { + "shortText": "Attaches callbacks for the resolution and/or rejection of the Promise." + } + }, + "@supabase/supabase-js.PostgrestFilterBuilder.throwOnError": { + "name": "@supabase/supabase-js.PostgrestFilterBuilder.throwOnError", + "params": [], + "comment": { + "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.\n\nhttps://github.com/supabase/supabase-js/issues/92" + } + }, + "@supabase/supabase-js.PostgrestQueryBuilder.constructor": { + "name": "@supabase/supabase-js.PostgrestQueryBuilder.constructor", + "params": [ + { + "name": "url", + "type": { + "type": "nameOnly", + "name": "URL" + }, + "comment": { + "shortText": "The URL for the query" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RequestInfo" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true, + "comment": { + "shortText": "Custom fetch implementation" + } + }, + { + "name": "headers", + "type": { + "type": "nameOnly", + "name": "HeadersInit" + }, + "isOptional": true, + "comment": { + "shortText": "Custom headers" + } + }, + { + "name": "retry", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Enable automatic retries for transient errors (default: true)" + } + }, + { + "name": "schema", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Postgres schema to use" + } + }, + { + "name": "urlLengthLimit", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "Maximum URL length before warning" + } + } + ] + }, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestQueryBuilder" + } + }, + "comment": { + "shortText": "Creates a query builder scoped to a Postgres table or view.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst { data, error } = await supabase.from('users').select('*')\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport { PostgrestQueryBuilder } from '@supabase/postgrest-js'\n\nconst query = new PostgrestQueryBuilder(\n new URL('https://xyzcompany.supabase.co/rest/v1/users'),\n { headers: { apikey: 'your-publishable-key' }, retry: true }\n)\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestQueryBuilder.delete": { + "name": "@supabase/supabase-js.PostgrestQueryBuilder.delete", + "params": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "count", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "exact" + }, + null, + { + "type": "literal", + "value": "planned" + }, + { + "type": "literal", + "value": "estimated" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Count algorithm to use to count deleted rows.\n\n`\"exact\"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the\nhood.\n\n`\"planned\"`: Approximated but fast count algorithm. Uses the Postgres\nstatistics under the hood.\n\n`\"estimated\"`: Uses exact count for low numbers and planned count for high\nnumbers." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Perform a DELETE on the table or view.\n\nBy default, deleted rows are not returned. To return it, chain the call\nwith `.select()` after filters.", + "text": "- `delete()` should always be combined with [filters](/docs/reference/javascript/using-filters) to target the item(s) you wish to delete.\n- If you use `delete()` with filters and you have\n [RLS](/docs/learn/auth-deep-dive/auth-row-level-security) enabled, only\n rows visible through `SELECT` policies are deleted. Note that by default\n no rows are visible, so you need at least one `SELECT`/`ALL` policy that\n makes the rows visible.\n- When using `delete().in()`, specify an array of values to target multiple rows with a single query. This is particularly useful for batch deleting entries that share common criteria, such as deleting users by their IDs. Ensure that the array you provide accurately represents all records you intend to delete to avoid unintended data removal.", + "examples": [ + { + "id": "delete-a-single-record", + "name": "Delete a single record", + "code": "```ts\nconst response = await supabase\n .from('countries')\n .delete()\n .eq('id', 1)\n```", + "data": { + "sql": "```sql\ncreate table\n countries (id int8 primary key, name text);\n\ninsert into\n countries (id, name)\nvalues\n (1, 'Mordor');\n```" + }, + "response": "```json\n{\n \"status\": 204,\n \"statusText\": \"No Content\"\n}\n```" + }, + { + "id": "handling-errors", + "name": "Handling errors", + "code": "```js\nconst { error } = await supabase.from('countries').delete().eq('id', 1)\nif (error) console.error(error)\n```", + "description": "`error.hint` from Postgres often contains the actionable fix (e.g. `\"Grant the required privileges to the current role with: GRANT DELETE ON public.countries TO anon;\"` for a `42501` permission-denied error). Log the full `error` object so it isn't hidden behind `error.message`." + }, + { + "id": "delete-a-record-and-return-it", + "name": "Delete a record and return it", + "code": "```ts\nconst { data, error } = await supabase\n .from('countries')\n .delete()\n .eq('id', 1)\n .select()\n```", + "data": { + "sql": "```sql\ncreate table\n countries (id int8 primary key, name text);\n\ninsert into\n countries (id, name)\nvalues\n (1, 'Mordor');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Mordor\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "delete-multiple-records", + "name": "Delete multiple records", + "code": "```ts\nconst response = await supabase\n .from('countries')\n .delete()\n .in('id', [1, 2, 3])\n```", + "data": { + "sql": "```sql\ncreate table\n countries (id int8 primary key, name text);\n\ninsert into\n countries (id, name)\nvalues\n (1, 'Rohan'), (2, 'The Shire'), (3, 'Mordor');\n```" + }, + "response": "```json\n{\n \"status\": 204,\n \"statusText\": \"No Content\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestQueryBuilder.insert": { + "name": "@supabase/supabase-js.PostgrestQueryBuilder.insert", + "params": [ + { + "name": "values", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RejectExcessProperties" + }, + { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "RejectExcessProperties" + } + } + ] + }, + "comment": { + "shortText": "The values to insert. Pass an object to insert a single row\nor an array to insert multiple rows." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "count", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "exact" + }, + null, + { + "type": "literal", + "value": "planned" + }, + { + "type": "literal", + "value": "estimated" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Count algorithm to use to count inserted rows.\n\n`\"exact\"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the\nhood.\n\n`\"planned\"`: Approximated but fast count algorithm. Uses the Postgres\nstatistics under the hood.\n\n`\"estimated\"`: Uses exact count for low numbers and planned count for high\nnumbers." + } + }, + { + "name": "defaultToNull", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Make missing fields default to `null`.\nOtherwise, use the default value for the column. Only applies for bulk\ninserts." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Perform an INSERT into the table or view.\n\nBy default, inserted rows are not returned. To return it, chain the call\nwith `.select()`.", + "examples": [ + { + "id": "create-a-record", + "name": "Create a record", + "code": "```ts\nconst { error } = await supabase\n .from('countries')\n .insert({ id: 1, name: 'Mordor' })\n```", + "data": { + "sql": "```sql\ncreate table\n countries (id int8 primary key, name text);\n```" + }, + "response": "```json\n{\n \"status\": 201,\n \"statusText\": \"Created\"\n}\n```" + }, + { + "id": "handling-errors", + "name": "Handling errors", + "code": "```js\nconst { error } = await supabase.from('countries').insert({ id: 1, name: 'Mordor' })\nif (error) console.error(error)\n```", + "description": "`error.hint` from Postgres often contains the actionable fix (e.g. `\"Grant the required privileges to the current role with: GRANT INSERT ON public.countries TO anon;\"` for a `42501` permission-denied error). Log the full `error` object so it isn't hidden behind `error.message`." + }, + { + "id": "create-a-record-and-return-it", + "name": "Create a record and return it", + "code": "```ts\nconst { data, error } = await supabase\n .from('countries')\n .insert({ id: 1, name: 'Mordor' })\n .select()\n```", + "data": { + "sql": "```sql\ncreate table\n countries (id int8 primary key, name text);\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Mordor\"\n }\n ],\n \"status\": 201,\n \"statusText\": \"Created\"\n}\n```" + }, + { + "id": "bulk-create", + "name": "Bulk create", + "code": "```ts\nconst { error } = await supabase\n .from('countries')\n .insert([\n { id: 1, name: 'Mordor' },\n { id: 1, name: 'The Shire' },\n ])\n```", + "description": "A bulk create operation is handled in a single transaction.\nIf any of the inserts fail, none of the rows are inserted.", + "data": { + "sql": "```sql\ncreate table\n countries (id int8 primary key, name text);\n```" + }, + "response": "```json\n{\n \"error\": {\n \"code\": \"23505\",\n \"details\": \"Key (id)=(1) already exists.\",\n \"hint\": null,\n \"message\": \"duplicate key value violates unique constraint \\\"countries_pkey\\\"\"\n },\n \"status\": 409,\n \"statusText\": \"Conflict\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestQueryBuilder.select": { + "name": "@supabase/supabase-js.PostgrestQueryBuilder.select", + "params": [ + { + "name": "columns", + "type": { + "type": "nameOnly", + "name": "Query" + }, + "isOptional": true, + "comment": { + "shortText": "The columns to retrieve, separated by commas. Columns can be renamed when returned with `customName:columnName`" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "count", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "exact" + }, + null, + { + "type": "literal", + "value": "planned" + }, + { + "type": "literal", + "value": "estimated" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Count algorithm to use to count rows in the table or view.\n\n`\"exact\"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the\nhood.\n\n`\"planned\"`: Approximated but fast count algorithm. Uses the Postgres\nstatistics under the hood.\n\n`\"estimated\"`: Uses exact count for low numbers and planned count for high\nnumbers." + } + }, + { + "name": "head", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "When set to `true`, `data` will not be returned.\nUseful if you only need the count." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Perform a SELECT query on the table or view.", + "text": "When using `count` with `.range()` or `.limit()`, the returned `count` is the total number of rows\nthat match your filters, not the number of rows in the current page. Use this to build pagination UI.\n\n- By default, Supabase projects return a maximum of 1,000 rows. This setting can be changed in your project's [API settings](/dashboard/project/_/settings/api). It's recommended that you keep it low to limit the payload size of accidental or malicious requests. You can use `range()` queries to paginate through your data.\n- `select()` can be combined with [Filters](/docs/reference/javascript/using-filters)\n- `select()` can be combined with [Modifiers](/docs/reference/javascript/using-modifiers)\n- `apikey` is a reserved keyword if you're using the [Supabase Platform](/docs/guides/platform) and [should be avoided as a column name](https://github.com/supabase/supabase/issues/5465). *", + "examples": [ + { + "id": "getting-your-data", + "name": "Getting your data", + "code": "```js\nconst { data, error } = await supabase\n .from('characters')\n .select()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Harry'),\n (2, 'Frodo'),\n (3, 'Katniss');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Harry\"\n },\n {\n \"id\": 2,\n \"name\": \"Frodo\"\n },\n {\n \"id\": 3,\n \"name\": \"Katniss\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "handling-errors", + "name": "Handling errors", + "code": "```js\nconst { data, error } = await supabase.from('characters').select()\nif (error) {\n // Logs the full error: message, code, details, and hint.\n console.error(error)\n return\n}\n```", + "description": "The most useful field on a Postgres error is usually `hint` — when the database knows the fix, it puts the literal SQL there. For example, a permission-denied error (`code: '42501'`) arrives with a `hint` like `\"Grant the required privileges to the current role with: GRANT SELECT ON public.characters TO anon;\"`. Log the full `error` object so the hint isn't hidden behind `error.message`.", + "response": "```json\n{\n \"error\": {\n \"code\": \"42501\",\n \"details\": null,\n \"hint\": \"Grant the required privileges to the current role with: GRANT SELECT ON public.characters TO anon;\",\n \"message\": \"permission denied for table characters\"\n },\n \"status\": 401,\n \"statusText\": \"Unauthorized\"\n}\n```" + }, + { + "id": "selecting-specific-columns", + "name": "Selecting specific columns", + "code": "```js\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Frodo'),\n (2, 'Harry'),\n (3, 'Katniss');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Frodo\"\n },\n {\n \"name\": \"Harry\"\n },\n {\n \"name\": \"Katniss\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "query-referenced-tables", + "name": "Query referenced tables", + "code": "```js\nconst { data, error } = await supabase\n .from('orchestral_sections')\n .select(`\n name,\n instruments (\n name\n )\n `)\n```", + "description": "If your database has foreign key relationships, you can query related tables too.", + "data": { + "sql": "```sql\ncreate table\n orchestral_sections (id int8 primary key, name text);\ncreate table\n instruments (\n id int8 primary key,\n section_id int8 not null references orchestral_sections,\n name text\n );\n\ninsert into\n orchestral_sections (id, name)\nvalues\n (1, 'strings'),\n (2, 'woodwinds');\ninsert into\n instruments (id, section_id, name)\nvalues\n (1, 2, 'flute'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"strings\",\n \"instruments\": [\n {\n \"name\": \"violin\"\n }\n ]\n },\n {\n \"name\": \"woodwinds\",\n \"instruments\": [\n {\n \"name\": \"flute\"\n }\n ]\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "query-referenced-tables-with-spaces-in-their-names", + "name": "Query referenced tables with spaces in their names", + "code": "```js\nconst { data, error } = await supabase\n .from('orchestral sections')\n .select(`\n name,\n \"musical instruments\" (\n name\n )\n `)\n```", + "description": "If your table name contains spaces, you must use double quotes in the `select` statement to reference the table.", + "data": { + "sql": "```sql\ncreate table\n \"orchestral sections\" (id int8 primary key, name text);\ncreate table\n \"musical instruments\" (\n id int8 primary key,\n section_id int8 not null references \"orchestral sections\",\n name text\n );\n\ninsert into\n \"orchestral sections\" (id, name)\nvalues\n (1, 'strings'),\n (2, 'woodwinds');\ninsert into\n \"musical instruments\" (id, section_id, name)\nvalues\n (1, 2, 'flute'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"strings\",\n \"musical instruments\": [\n {\n \"name\": \"violin\"\n }\n ]\n },\n {\n \"name\": \"woodwinds\",\n \"musical instruments\": [\n {\n \"name\": \"flute\"\n }\n ]\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "query-referenced-tables-through-a-join-table", + "name": "Query referenced tables through a join table", + "code": "```ts\nconst { data, error } = await supabase\n .from('users')\n .select(`\n name,\n teams (\n name\n )\n `)\n\n```", + "description": "If you're in a situation where your tables are **NOT** directly\nrelated, but instead are joined by a _join table_, you can still use\nthe `select()` method to query the related data. The join table needs\nto have the foreign keys as part of its composite primary key.", + "data": { + "sql": "```sql\ncreate table\n users (\n id int8 primary key,\n name text\n );\ncreate table\n teams (\n id int8 primary key,\n name text\n );\n-- join table\ncreate table\n users_teams (\n user_id int8 not null references users,\n team_id int8 not null references teams,\n -- both foreign keys must be part of a composite primary key\n primary key (user_id, team_id)\n );\n\ninsert into\n users (id, name)\nvalues\n (1, 'Kiran'),\n (2, 'Evan');\ninsert into\n teams (id, name)\nvalues\n (1, 'Green'),\n (2, 'Blue');\ninsert into\n users_teams (user_id, team_id)\nvalues\n (1, 1),\n (1, 2),\n (2, 2);\n```" + }, + "response": "```json\n {\n \"data\": [\n {\n \"name\": \"Kiran\",\n \"teams\": [\n {\n \"name\": \"Green\"\n },\n {\n \"name\": \"Blue\"\n }\n ]\n },\n {\n \"name\": \"Evan\",\n \"teams\": [\n {\n \"name\": \"Blue\"\n }\n ]\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n }\n\n```" + }, + { + "id": "query-the-same-referenced-table-multiple-times", + "name": "Query the same referenced table multiple times", + "code": "```ts\nconst { data, error } = await supabase\n .from('messages')\n .select(`\n content,\n from:sender_id(name),\n to:receiver_id(name)\n `)\n\n// To infer types, use the name of the table (in this case `users`) and\n// the name of the foreign key constraint.\nconst { data, error } = await supabase\n .from('messages')\n .select(`\n content,\n from:users!messages_sender_id_fkey(name),\n to:users!messages_receiver_id_fkey(name)\n `)\n```", + "description": "If you need to query the same referenced table twice, use the name of the\njoined column to identify which join to use. You can also give each\ncolumn an alias.", + "data": { + "sql": "```sql\n create table\n users (id int8 primary key, name text);\n\n create table\n messages (\n sender_id int8 not null references users,\n receiver_id int8 not null references users,\n content text\n );\n\n insert into\n users (id, name)\n values\n (1, 'Kiran'),\n (2, 'Evan');\n\n insert into\n messages (sender_id, receiver_id, content)\n values\n (1, 2, '👋');\n ```\n```\n\n@exampleResponse Query the same referenced table multiple times\n```json\n{\n \"data\": [\n {\n \"content\": \"👋\",\n \"from\": {\n \"name\": \"Kiran\"\n },\n \"to\": {\n \"name\": \"Evan\"\n }\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```\n\n@exampleDescription Query nested foreign tables through a join table\nYou can use the result of a joined table to gather data in\nanother foreign table. With multiple references to the same foreign\ntable you must specify the column on which to conduct the join.\n\n@example Query nested foreign tables through a join table\n```ts\n const { data, error } = await supabase\n .from('games')\n .select(`\n game_id:id,\n away_team:teams!games_away_team_fkey (\n users (\n id,\n name\n )\n )\n `)\n\n```\n\n@exampleSql Query nested foreign tables through a join table\n```sql\n```sql\ncreate table\n users (\n id int8 primary key,\n name text\n );\ncreate table\n teams (\n id int8 primary key,\n name text\n );\n-- join table\ncreate table\n users_teams (\n user_id int8 not null references users,\n team_id int8 not null references teams,\n\n primary key (user_id, team_id)\n );\ncreate table\n games (\n id int8 primary key,\n home_team int8 not null references teams,\n away_team int8 not null references teams,\n name text\n );\n\ninsert into users (id, name)\nvalues\n (1, 'Kiran'),\n (2, 'Evan');\ninsert into\n teams (id, name)\nvalues\n (1, 'Green'),\n (2, 'Blue');\ninsert into\n users_teams (user_id, team_id)\nvalues\n (1, 1),\n (1, 2),\n (2, 2);\ninsert into\n games (id, home_team, away_team, name)\nvalues\n (1, 1, 2, 'Green vs Blue'),\n (2, 2, 1, 'Blue vs Green');\n```" + } + }, + { + "id": "filtering-through-referenced-tables", + "name": "Filtering through referenced tables", + "code": "```ts\nconst { data, error } = await supabase\n .from('instruments')\n .select('name, orchestral_sections(*)')\n .eq('orchestral_sections.name', 'percussion')\n```", + "description": "If the filter on a referenced table's column is not satisfied, the referenced\ntable returns `[]` or `null` but the parent table is not filtered out.\nIf you want to filter out the parent table rows, use the `!inner` hint", + "data": { + "sql": "```sql\ncreate table\n orchestral_sections (id int8 primary key, name text);\ncreate table\n instruments (\n id int8 primary key,\n section_id int8 not null references orchestral_sections,\n name text\n );\n\ninsert into\n orchestral_sections (id, name)\nvalues\n (1, 'strings'),\n (2, 'woodwinds');\ninsert into\n instruments (id, section_id, name)\nvalues\n (1, 2, 'flute'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"flute\",\n \"orchestral_sections\": null\n },\n {\n \"name\": \"violin\",\n \"orchestral_sections\": null\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "querying-referenced-table-with-count", + "name": "Querying referenced table with count", + "code": "```ts\nconst { data, error } = await supabase\n .from('orchestral_sections')\n .select(`*, instruments(count)`)\n```", + "description": "You can get the number of rows in a related table by using the\n**count** property.", + "data": { + "sql": "```sql\ncreate table orchestral_sections (\n \"id\" \"uuid\" primary key default \"extensions\".\"uuid_generate_v4\"() not null,\n \"name\" text\n);\n\ncreate table characters (\n \"id\" \"uuid\" primary key default \"extensions\".\"uuid_generate_v4\"() not null,\n \"name\" text,\n \"section_id\" \"uuid\" references public.orchestral_sections on delete cascade\n);\n\nwith section as (\n insert into orchestral_sections (name)\n values ('strings') returning id\n)\ninsert into instruments (name, section_id) values\n('violin', (select id from section)),\n('viola', (select id from section)),\n('cello', (select id from section)),\n('double bass', (select id from section));\n```" + }, + "response": "```json\n[\n {\n \"id\": \"693694e7-d993-4360-a6d7-6294e325d9b6\",\n \"name\": \"strings\",\n \"instruments\": [\n {\n \"count\": 4\n }\n ]\n }\n]\n```" + }, + { + "id": "querying-with-count-option", + "name": "Querying with count option", + "code": "```ts\nconst { count, error } = await supabase\n .from('characters')\n .select('*', { count: 'exact', head: true })\n```", + "description": "You can get the number of rows by using the\n[count](/docs/reference/javascript/select#parameters) option.", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"count\": 3,\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "querying-json-data", + "name": "Querying JSON data", + "code": "```ts\nconst { data, error } = await supabase\n .from('users')\n .select(`\n id, name,\n address->city\n `)\n```", + "description": "You can select and filter data inside of\n[JSON](/docs/guides/database/json) columns. Postgres offers some\n[operators](/docs/guides/database/json#query-the-jsonb-data) for\nquerying JSON data.", + "data": { + "sql": "```sql\ncreate table\n users (\n id int8 primary key,\n name text,\n address jsonb\n );\n\ninsert into\n users (id, name, address)\nvalues\n (1, 'Frodo', '{\"city\":\"Hobbiton\"}');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Frodo\",\n \"city\": \"Hobbiton\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "querying-referenced-table-with-inner-join", + "name": "Querying referenced table with inner join", + "code": "```ts\nconst { data, error } = await supabase\n .from('instruments')\n .select('name, orchestral_sections!inner(name)')\n .eq('orchestral_sections.name', 'woodwinds')\n .limit(1)\n```", + "description": "If you don't want to return the referenced table contents, you can leave the parenthesis empty.\nLike `.select('name, orchestral_sections!inner()')`.", + "data": { + "sql": "```sql\ncreate table orchestral_sections (\n \"id\" \"uuid\" primary key default \"extensions\".\"uuid_generate_v4\"() not null,\n \"name\" text\n);\n\ncreate table instruments (\n \"id\" \"uuid\" primary key default \"extensions\".\"uuid_generate_v4\"() not null,\n \"name\" text,\n \"section_id\" \"uuid\" references public.orchestral_sections on delete cascade\n);\n\nwith section as (\n insert into orchestral_sections (name)\n values ('woodwinds') returning id\n)\ninsert into instruments (name, section_id) values\n('flute', (select id from section)),\n('clarinet', (select id from section)),\n('bassoon', (select id from section)),\n('piccolo', (select id from section));\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"flute\",\n \"orchestral_sections\": {\"name\": \"woodwinds\"}\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "switching-schemas-per-query", + "name": "Switching schemas per query", + "code": "```ts\nconst { data, error } = await supabase\n .schema('myschema')\n .from('mytable')\n .select()\n```", + "description": "In addition to setting the schema during initialization, you can also switch schemas on a per-query basis.\nMake sure you've set up your [database privileges and API settings](/docs/guides/api/using-custom-schemas).", + "data": { + "sql": "```sql\ncreate schema myschema;\n\ncreate table myschema.mytable (\n id uuid primary key default gen_random_uuid(),\n data text\n);\n\ninsert into myschema.mytable (data) values ('mydata');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": \"4162e008-27b0-4c0f-82dc-ccaeee9a624d\",\n \"data\": \"mydata\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestQueryBuilder.update": { + "name": "@supabase/supabase-js.PostgrestQueryBuilder.update", + "params": [ + { + "name": "values", + "type": { + "type": "nameOnly", + "name": "RejectExcessProperties" + }, + "comment": { + "shortText": "The values to update with" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "count", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "exact" + }, + null, + { + "type": "literal", + "value": "planned" + }, + { + "type": "literal", + "value": "estimated" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Count algorithm to use to count updated rows.\n\n`\"exact\"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the\nhood.\n\n`\"planned\"`: Approximated but fast count algorithm. Uses the Postgres\nstatistics under the hood.\n\n`\"estimated\"`: Uses exact count for low numbers and planned count for high\nnumbers." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Perform an UPDATE on the table or view.\n\nBy default, updated rows are not returned. To return it, chain the call\nwith `.select()` after filters.", + "text": "- `update()` should always be combined with [Filters](/docs/reference/javascript/using-filters) to target the item(s) you wish to update.", + "examples": [ + { + "id": "updating-your-data", + "name": "Updating your data", + "code": "```ts\nconst { error } = await supabase\n .from('instruments')\n .update({ name: 'piano' })\n .eq('id', 1)\n```", + "data": { + "sql": "```sql\ncreate table\n instruments (id int8 primary key, name text);\n\ninsert into\n instruments (id, name)\nvalues\n (1, 'harpsichord');\n```" + }, + "response": "```json\n{\n \"status\": 204,\n \"statusText\": \"No Content\"\n}\n```" + }, + { + "id": "handling-errors", + "name": "Handling errors", + "code": "```js\nconst { error } = await supabase.from('instruments').update({ name: 'piano' }).eq('id', 1)\nif (error) console.error(error)\n```", + "description": "`error.hint` from Postgres often contains the actionable fix (e.g. `\"Grant the required privileges to the current role with: GRANT UPDATE ON public.instruments TO anon;\"` for a `42501` permission-denied error). Log the full `error` object so it isn't hidden behind `error.message`." + }, + { + "id": "update-a-record-and-return-it", + "name": "Update a record and return it", + "code": "```ts\nconst { data, error } = await supabase\n .from('instruments')\n .update({ name: 'piano' })\n .eq('id', 1)\n .select()\n```", + "data": { + "sql": "```sql\ncreate table\n instruments (id int8 primary key, name text);\n\ninsert into\n instruments (id, name)\nvalues\n (1, 'harpsichord');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"piano\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "updating-json-data", + "name": "Updating JSON data", + "code": "```ts\nconst { data, error } = await supabase\n .from('users')\n .update({\n address: {\n street: 'Melrose Place',\n postcode: 90210\n }\n })\n .eq('address->postcode', 90210)\n .select()\n```", + "description": "Postgres offers some\n[operators](/docs/guides/database/json#query-the-jsonb-data) for\nworking with JSON data. Currently, it is only possible to update the entire JSON document.", + "data": { + "sql": "```sql\ncreate table\n users (\n id int8 primary key,\n name text,\n address jsonb\n );\n\ninsert into\n users (id, name, address)\nvalues\n (1, 'Michael', '{ \"postcode\": 90210 }');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Michael\",\n \"address\": {\n \"street\": \"Melrose Place\",\n \"postcode\": 90210\n }\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestQueryBuilder.upsert": { + "name": "@supabase/supabase-js.PostgrestQueryBuilder.upsert", + "params": [ + { + "name": "values", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RejectExcessProperties" + }, + { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "RejectExcessProperties" + } + } + ] + }, + "comment": { + "shortText": "The values to upsert with. Pass an object to upsert a\nsingle row or an array to upsert multiple rows." + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "count", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "exact" + }, + null, + { + "type": "literal", + "value": "planned" + }, + { + "type": "literal", + "value": "estimated" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Count algorithm to use to count upserted rows.\n\n`\"exact\"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the\nhood.\n\n`\"planned\"`: Approximated but fast count algorithm. Uses the Postgres\nstatistics under the hood.\n\n`\"estimated\"`: Uses exact count for low numbers and planned count for high\nnumbers." + } + }, + { + "name": "defaultToNull", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Make missing fields default to `null`.\nOtherwise, use the default value for the column. This only applies when\ninserting new rows, not when merging with existing rows under\n`ignoreDuplicates: false`. This also only applies when doing bulk upserts." + } + }, + { + "name": "ignoreDuplicates", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, duplicate rows are ignored. If\n`false`, duplicate rows are merged with existing rows." + } + }, + { + "name": "onConflict", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Comma-separated UNIQUE column(s) to specify how\nduplicate rows are determined. Two rows are duplicates if all the\n`onConflict` columns are equal." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Perform an UPSERT on the table or view. Depending on the column(s) passed\nto `onConflict`, `.upsert()` allows you to perform the equivalent of\n`.insert()` if a row with the corresponding `onConflict` columns doesn't\nexist, or if it does exist, perform an alternative action depending on\n`ignoreDuplicates`.\n\nBy default, upserted rows are not returned. To return it, chain the call\nwith `.select()`.", + "text": "- Primary keys must be included in `values` to use upsert.", + "examples": [ + { + "id": "upsert-a-single-row-using-a-unique-key", + "name": "Upsert a single row using a unique key", + "code": "```ts\n// Upserting a single row, overwriting based on the 'username' unique column\nconst { data, error } = await supabase\n .from('users')\n .upsert({ username: 'supabot' }, { onConflict: 'username' })\n\n// Example response:\n// {\n// data: [\n// { id: 4, message: 'bar', username: 'supabot' }\n// ],\n// error: null\n// }\n```" + }, + { + "id": "upsert-with-conflict-resolution-and-exact-row-counting", + "name": "Upsert with conflict resolution and exact row counting", + "code": "```ts\n// Upserting and returning exact count\nconst { data, error, count } = await supabase\n .from('users')\n .upsert(\n {\n id: 3,\n message: 'foo',\n username: 'supabot'\n },\n {\n onConflict: 'username',\n count: 'exact'\n }\n )\n\n// Example response:\n// {\n// data: [\n// {\n// id: 42,\n// handle: \"saoirse\",\n// display_name: \"Saoirse\"\n// }\n// ],\n// count: 1,\n// error: null\n// }\n```" + }, + { + "id": "upsert-your-data", + "name": "Upsert your data", + "code": "```ts\nconst { data, error } = await supabase\n .from('instruments')\n .upsert({ id: 1, name: 'piano' })\n .select()\n```", + "data": { + "sql": "```sql\ncreate table\n instruments (id int8 primary key, name text);\n\ninsert into\n instruments (id, name)\nvalues\n (1, 'harpsichord');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"piano\"\n }\n ],\n \"status\": 201,\n \"statusText\": \"Created\"\n}\n```" + }, + { + "id": "handling-errors", + "name": "Handling errors", + "code": "```js\nconst { data, error } = await supabase.from('instruments').upsert({ id: 1, name: 'piano' }).select()\nif (error) console.error(error)\n```", + "description": "`error.hint` from Postgres often contains the actionable fix (e.g. `\"Grant the required privileges to the current role with: GRANT INSERT, UPDATE ON public.instruments TO anon;\"` for a `42501` permission-denied error). Log the full `error` object so it isn't hidden behind `error.message`." + }, + { + "id": "bulk-upsert-your-data", + "name": "Bulk Upsert your data", + "code": "```ts\nconst { data, error } = await supabase\n .from('instruments')\n .upsert([\n { id: 1, name: 'piano' },\n { id: 2, name: 'harp' },\n ])\n .select()\n```", + "data": { + "sql": "```sql\ncreate table\n instruments (id int8 primary key, name text);\n\ninsert into\n instruments (id, name)\nvalues\n (1, 'harpsichord');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"piano\"\n },\n {\n \"id\": 2,\n \"name\": \"harp\"\n }\n ],\n \"status\": 201,\n \"statusText\": \"Created\"\n}\n```" + }, + { + "id": "upserting-into-tables-with-constraints", + "name": "Upserting into tables with constraints", + "code": "```ts\nconst { data, error } = await supabase\n .from('users')\n .upsert({ id: 42, handle: 'saoirse', display_name: 'Saoirse' })\n .select()\n```", + "description": "In the following query, `upsert()` implicitly uses the `id`\n(primary key) column to determine conflicts. If there is no existing\nrow with the same `id`, `upsert()` inserts a new row, which\nwill fail in this case as there is already a row with `handle` `\"saoirse\"`.\nUsing the `onConflict` option, you can instruct `upsert()` to use\nanother column with a unique constraint to determine conflicts.", + "data": { + "sql": "```sql\ncreate table\n users (\n id int8 generated by default as identity primary key,\n handle text not null unique,\n display_name text\n );\n\ninsert into\n users (id, handle, display_name)\nvalues\n (1, 'saoirse', null);\n```" + }, + "response": "```json\n{\n \"error\": {\n \"code\": \"23505\",\n \"details\": \"Key (handle)=(saoirse) already exists.\",\n \"hint\": null,\n \"message\": \"duplicate key value violates unique constraint \\\"users_handle_key\\\"\"\n },\n \"status\": 409,\n \"statusText\": \"Conflict\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.constructor": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.constructor", + "params": [ + { + "name": "builder", + "type": { + "type": "object", + "properties": [ + { + "name": "body", + "type": { + "type": "intrinsic", + "name": "unknown" + }, + "isOptional": true + }, + { + "name": "fetch", + "type": { + "type": "function", + "params": [ + { + "name": "input", + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "RequestInfo" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "init", + "type": { + "type": "nameOnly", + "name": "RequestInit" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "Response" + } + } + }, + "comment": { + "shortText": "[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)" + } + }, + "isOptional": true + }, + { + "name": "headers", + "type": { + "type": "nameOnly", + "name": "HeadersInit" + } + }, + { + "name": "isMaybeSingle", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "method", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "GET" + }, + { + "type": "literal", + "value": "POST" + }, + { + "type": "literal", + "value": "PATCH" + }, + { + "type": "literal", + "value": "DELETE" + }, + { + "type": "literal", + "value": "HEAD" + } + ] + } + }, + { + "name": "retry", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "schema", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "shouldStripNulls", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "shouldThrowOnError", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "isOptional": true + }, + { + "name": "url", + "type": { + "type": "nameOnly", + "name": "URL" + } + }, + { + "name": "urlLengthLimit", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + } + ] + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestTransformBuilder" + } + }, + "comment": { + "shortText": "Creates a builder configured for a specific PostgREST request.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst { data, error } = await supabase.from('users').select('*')\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport { PostgrestQueryBuilder } from '@supabase/postgrest-js'\n\nconst builder = new PostgrestQueryBuilder(\n new URL('https://xyzcompany.supabase.co/rest/v1/users'),\n { headers: new Headers({ apikey: 'your-publishable-key' }) }\n)\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.abortSignal": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.abortSignal", + "params": [ + { + "name": "signal", + "type": { + "type": "nameOnly", + "name": "AbortSignal" + }, + "comment": { + "shortText": "The AbortSignal to use for the fetch request" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set the AbortSignal for the fetch request.", + "text": "You can use this to set a timeout for the request.", + "examples": [ + { + "id": "aborting-requests-in-flight", + "name": "Aborting requests in-flight", + "code": "```ts\nconst ac = new AbortController()\n\nconst { data, error } = await supabase\n .from('very_big_table')\n .select()\n .abortSignal(ac.signal)\n\n// Abort the request after 100 ms\nsetTimeout(() => ac.abort(), 100)\n```", + "description": "You can use an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) to abort requests.\nNote that `status` and `statusText` don't mean anything for aborted requests as the request wasn't fulfilled.", + "response": "```json\n {\n \"error\": {\n \"message\": \"AbortError: The user aborted a request.\",\n \"details\": \"\",\n \"hint\": \"The request was aborted locally via the provided AbortSignal.\",\n \"code\": \"\"\n },\n \"status\": 0,\n \"statusText\": \"\"\n }\n\n```" + }, + { + "id": "set-a-timeout", + "name": "Set a timeout", + "code": "```ts\nconst { data, error } = await supabase\n .from('very_big_table')\n .select()\n .abortSignal(AbortSignal.timeout(1000 /* ms */))\n```", + "response": "```json\n {\n \"error\": {\n \"message\": \"FetchError: The user aborted a request.\",\n \"details\": \"\",\n \"hint\": \"\",\n \"code\": \"\"\n },\n \"status\": 400,\n \"statusText\": \"Bad Request\"\n }\n\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.csv": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.csv", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Return `data` as a string in CSV format.", + "examples": [ + { + "id": "return-data-as-csv", + "name": "Return data as CSV", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .csv()\n```", + "description": "By default, the data is returned in JSON format, but can also be returned as Comma Separated Values.", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": \"id,name\\n1,Luke\\n2,Leia\\n3,Han\",\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.explain": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.explain", + "params": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "analyze", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, the query will be executed and the\nactual run time will be returned" + } + }, + { + "name": "buffers", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, include information on buffer usage" + } + }, + { + "name": "format", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "text" + }, + { + "type": "literal", + "value": "json" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The format of the output, can be `\"text\"` (default)\nor `\"json\"`" + } + }, + { + "name": "settings", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, include information on configuration\nparameters that affect query planning" + } + }, + { + "name": "verbose", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, the query identifier will be returned\nand `data` will include the output columns of the query" + } + }, + { + "name": "wal", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If `true`, include information on WAL record generation" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "PostgrestBuilder" + }, + { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + ] + } + }, + "comment": { + "shortText": "Return `data` as the EXPLAIN plan for the query.\n\nYou need to enable the\n[db_plan_enabled](https://supabase.com/docs/guides/database/debugging-performance#enabling-explain)\nsetting before using this method.", + "examples": [ + { + "id": "get-the-execution-plan", + "name": "Get the execution plan", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .explain()\n```", + "description": "By default, the data is returned in TEXT format, but can also be returned as JSON by using the `format` parameter.", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```js\nAggregate (cost=33.34..33.36 rows=1 width=112)\n -> Limit (cost=0.00..18.33 rows=1000 width=40)\n -> Seq Scan on characters (cost=0.00..22.00 rows=1200 width=40)\n```" + }, + { + "id": "get-the-execution-plan-with-analyze-and-verbose", + "name": "Get the execution plan with analyze and verbose", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .explain({analyze:true,verbose:true})\n```", + "description": "By default, the data is returned in TEXT format, but can also be returned as JSON by using the `format` parameter.", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```js\nAggregate (cost=33.34..33.36 rows=1 width=112) (actual time=0.041..0.041 rows=1 loops=1)\n Output: NULL::bigint, count(ROW(characters.id, characters.name)), COALESCE(json_agg(ROW(characters.id, characters.name)), '[]'::json), NULLIF(current_setting('response.headers'::text, true), ''::text), NULLIF(current_setting('response.status'::text, true), ''::text)\n -> Limit (cost=0.00..18.33 rows=1000 width=40) (actual time=0.005..0.006 rows=3 loops=1)\n Output: characters.id, characters.name\n -> Seq Scan on public.characters (cost=0.00..22.00 rows=1200 width=40) (actual time=0.004..0.005 rows=3 loops=1)\n Output: characters.id, characters.name\nQuery Identifier: -4730654291623321173\nPlanning Time: 0.407 ms\nExecution Time: 0.119 ms\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.geojson": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.geojson", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Return `data` as an object in [GeoJSON](https://geojson.org) format." + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.limit": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.limit", + "params": [ + { + "name": "rows", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The maximum number of rows to return" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Deprecated, use `options.referencedTable`\ninstead" + } + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Set this to limit rows of referenced\ntables instead of the parent table" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Limit the query result by `rows`.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .limit(1)\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Luke\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + }, + { + "id": "on-a-referenced-table", + "name": "On a referenced table", + "code": "```ts\nconst { data, error } = await supabase\n .from('orchestral_sections')\n .select(`\n name,\n instruments (\n name\n )\n `)\n .limit(1, { referencedTable: 'instruments' })\n```", + "data": { + "sql": "```sql\ncreate table\n orchestral_sections (id int8 primary key, name text);\ncreate table\n instruments (\n id int8 primary key,\n section_id int8 not null references orchestral_sections,\n name text\n );\n\ninsert into\n orchestral_sections (id, name)\nvalues\n (1, 'strings');\ninsert into\n instruments (id, section_id, name)\nvalues\n (1, 1, 'harp'),\n (2, 1, 'violin');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"strings\",\n \"instruments\": [\n {\n \"name\": \"violin\"\n }\n ]\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.maxAffected": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.maxAffected", + "params": [ + { + "name": "rows", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The maximum number of rows that can be affected" + } + } + ], + "comment": { + "shortText": "Set the maximum number of rows that can be affected by the query.\nOnly available in PostgREST v13+ and only works with PATCH and DELETE methods." + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.maybeSingle": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.maybeSingle", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Return `data` as a single object instead of an array of objects.\n\nQuery result must be zero or one row (e.g. using `.limit(1)`), otherwise\nthis returns an error.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .eq('name', 'Katniss')\n .maybeSingle()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.order": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.order", + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "ascending", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "nullsFirst", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "undefined" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "altSignatures": [ + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "ascending", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "nullsFirst", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + }, + { + "params": [ + { + "name": "column", + "type": { + "type": "nameOnly", + "name": "ColumnName" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "ascending", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "undefined" + }, + "isOptional": true + }, + { + "name": "nullsFirst", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + }, + { + "params": [ + { + "name": "column", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "ascending", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "nullsFirst", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + } + } + ] + }, + "@supabase/supabase-js.PostgrestTransformBuilder.overrideTypes": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.overrideTypes", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Override the type of the returned `data` field in the response.", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```typescript\n// Merge with existing types (default behavior)\nconst query = supabase\n .from('users')\n .select()\n .overrideTypes<{ custom_field: string }>()\n\n// Replace existing types completely\nconst replaceQuery = supabase\n .from('users')\n .select()\n .overrideTypes<{ id: number; name: string }, { merge: false }>()\n```" + }, + { + "id": "complete-override-type-of-successful-response", + "name": "Complete Override type of successful response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .overrideTypes, { merge: false }>()\n```", + "response": "```ts\nlet x: typeof data // MyType[]\n```" + }, + { + "id": "complete-override-type-of-object-response", + "name": "Complete Override type of object response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .maybeSingle()\n .overrideTypes()\n```", + "response": "```ts\nlet x: typeof data // MyType | null\n```" + }, + { + "id": "partial-override-type-of-successful-response", + "name": "Partial Override type of successful response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .overrideTypes>()\n```", + "response": "```ts\nlet x: typeof data // Array\n```" + }, + { + "id": "partial-override-type-of-object-response", + "name": "Partial Override type of object response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .maybeSingle()\n .overrideTypes<{ status: \"A\" | \"B\" }>()\n```", + "response": "```ts\nlet x: typeof data // CountryRowProperties & { status: \"A\" | \"B\" } | null\n```" + }, + { + "id": "merge-vs-replace-existing-types", + "name": "Merge vs replace existing types", + "code": "```typescript\n// Merge with existing types (default behavior)\nconst query = supabase\n .from('users')\n .select()\n .overrideTypes<{ custom_field: string }>()\n\n// Replace existing types completely\nconst replaceQuery = supabase\n .from('users')\n .select()\n .overrideTypes<{ id: number; name: string }, { merge: false }>()\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.range": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.range", + "params": [ + { + "name": "from", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The starting index from which to limit the result" + } + }, + { + "name": "to", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "The last index to which to limit the result" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "foreignTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Deprecated, use `options.referencedTable`\ninstead" + } + }, + { + "name": "referencedTable", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Set this to limit rows of referenced\ntables instead of the parent table" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Limit the query result by starting at an offset `from` and ending at the offset `to`.\nOnly records within this range are returned.\nThis respects the query order and if there is no order clause the range could behave unexpectedly.\nThe `from` and `to` values are 0-based and inclusive: `range(1, 3)` will include the second, third\nand fourth rows of the query.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .range(0, 1)\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"name\": \"Luke\"\n },\n {\n \"name\": \"Leia\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.retry": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.retry", + "params": [ + { + "name": "enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "comment": { + "shortText": "Whether to enable retries for this request" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\n// Disable retries for a specific query\nconst { data, error } = await supabase\n .from('users')\n .select()\n .retry(false)\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.returns": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.returns", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestTransformBuilder" + } + }, + "comment": { + "shortText": "Override the type of the returned `data`.", + "text": "- Deprecated: use overrideTypes method instead", + "examples": [ + { + "id": "override-type-of-successful-response", + "name": "Override type of successful response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .returns>()\n```", + "response": "```js\nlet x: typeof data // MyType[]\n```" + }, + { + "id": "override-type-of-object-response", + "name": "Override type of object response", + "code": "```ts\nconst { data } = await supabase\n .from('countries')\n .select()\n .maybeSingle()\n .returns()\n```", + "response": "```js\nlet x: typeof data // MyType | null\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.rollback": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.rollback", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Rollback the query.\n\n`data` will still be returned, but the query is not committed." + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.select": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.select", + "params": [ + { + "name": "columns", + "type": { + "type": "nameOnly", + "name": "Query" + }, + "isOptional": true, + "comment": { + "shortText": "The columns to retrieve, separated by commas" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Perform a SELECT on the query result.\n\nBy default, `.insert()`, `.update()`, `.upsert()`, and `.delete()` do not\nreturn modified rows. By calling this method, modified rows are returned in\n`data`.", + "examples": [ + { + "id": "with-upsert", + "name": "With `upsert()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .upsert({ id: 1, name: 'Han Solo' })\n .select()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Han Solo\"\n }\n ],\n \"status\": 201,\n \"statusText\": \"Created\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.setHeader": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.setHeader", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "value", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Set an HTTP header for the request." + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.single": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.single", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, + "comment": { + "shortText": "Return `data` as a single object instead of an array of objects.\n\nQuery result must be one row (e.g. using `.limit(1)`), otherwise this\nreturns an error.", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select('name')\n .limit(1)\n .single()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text);\n\ninsert into\n characters (id, name)\nvalues\n (1, 'Luke'),\n (2, 'Leia'),\n (3, 'Han');\n```" + }, + "response": "```json\n{\n \"data\": {\n \"name\": \"Luke\"\n },\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.stripNulls": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.stripNulls", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "this" + } + }, + "comment": { + "shortText": "Strip null values from the response data. Properties with `null` values\nwill be omitted from the returned JSON objects.\n\nRequires PostgREST 11.2.0+.\n\nhttps://docs.postgrest.org/en/stable/references/api/resource_representation.html#stripped-nulls", + "examples": [ + { + "id": "with-select", + "name": "With `select()`", + "code": "```ts\nconst { data, error } = await supabase\n .from('characters')\n .select()\n .stripNulls()\n```", + "data": { + "sql": "```sql\ncreate table\n characters (id int8 primary key, name text, bio text);\n\ninsert into\n characters (id, name, bio)\nvalues\n (1, 'Luke', null),\n (2, 'Leia', 'Princess of Alderaan');\n```" + }, + "response": "```json\n{\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Luke\"\n },\n {\n \"id\": 2,\n \"name\": \"Leia\",\n \"bio\": \"Princess of Alderaan\"\n }\n ],\n \"status\": 200,\n \"statusText\": \"OK\"\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.then": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.then", + "params": [ + { + "name": "onfulfilled", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "value", + "type": { + "type": "union", + "name": "PostgrestSingleResponse", + "subTypes": [ + { + "type": "nameOnly", + "name": "PostgrestResponseSuccess" + }, + { + "type": "nameOnly", + "name": "PostgrestResponseFailure" + } + ] + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult1" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is resolved." + } + }, + { + "name": "onrejected", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "reason", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "union", + "subTypes": [ + { + "type": "nameOnly", + "name": "TResult2" + }, + { + "type": "nameOnly", + "name": "PromiseLike" + } + ] + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The callback to execute when the Promise is rejected." + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PromiseLike" + } + }, + "comment": { + "shortText": "Attaches callbacks for the resolution and/or rejection of the Promise." + } + }, + "@supabase/supabase-js.PostgrestTransformBuilder.throwOnError": { + "name": "@supabase/supabase-js.PostgrestTransformBuilder.throwOnError", + "params": [], + "comment": { + "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.\n\nhttps://github.com/supabase/supabase-js/issues/92" + } + }, + "@supabase/supabase-js.RealtimeChannel.constructor": { + "name": "@supabase/supabase-js.RealtimeChannel.constructor", + "params": [ + { + "name": "topic", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Topic name can be any string." + } + }, + { + "name": "params", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "name": "RealtimeChannelOptions", + "type": "object", + "properties": [ + { + "name": "config", + "type": { + "type": "object", + "properties": [ + { + "name": "broadcast", + "type": { + "type": "object", + "properties": [ + { + "name": "ack", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "replay", + "type": { + "type": "nameOnly", + "name": "ReplayOption" + }, + "isOptional": true + }, + { + "name": "self", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "self option enables client to receive message it broadcast\nack option instructs server to acknowledge that broadcast message was received\nreplay option instructs server to replay broadcast messages" + } + }, + { + "name": "presence", + "type": { + "type": "object", + "properties": [ + { + "name": "enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "key", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "key option is used to track presence payload across clients" + } + }, + { + "name": "private", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "defines if the channel is private or not and if RLS policies will be used to check data" + } + } + ] + } + } + ] + } + ] + } + }, + { + "name": "socket", + "type": { + "type": "nameOnly", + "name": "RealtimeClient" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + }, + "comment": { + "shortText": "Creates a channel that can broadcast messages, sync presence, and listen to Postgres changes.\n\nThe topic determines which realtime stream you are subscribing to. Config options let you\nenable acknowledgement for broadcasts, presence tracking, or private channels.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst channel = supabase.channel('room1')\nchannel\n .on('broadcast', { event: 'cursor-pos' }, (payload) => console.log(payload))\n .subscribe()\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport RealtimeClient from '@supabase/realtime-js'\n\nconst client = new RealtimeClient('https://xyzcompany.supabase.co/realtime/v1', {\n params: { apikey: 'your-publishable-key' },\n})\nconst channel = new RealtimeChannel('realtime:public:messages', { config: {} }, client)\n```" + } + ] + } + }, + "@supabase/supabase-js.RealtimeChannel.copyBindings": { + "name": "@supabase/supabase-js.RealtimeChannel.copyBindings", + "params": [ + { + "name": "other", + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + }, + "@supabase/supabase-js.RealtimeChannel.httpSend": { + "name": "@supabase/supabase-js.RealtimeChannel.httpSend", + "params": [ + { + "name": "event", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The name of the broadcast event" + } + }, + { + "name": "payload", + "type": { + "type": "intrinsic", + "name": "any" + }, + "comment": { + "shortText": "Payload to be sent (required)" + } + }, + { + "name": "opts", + "type": { + "type": "object", + "properties": [ + { + "name": "timeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Options including timeout" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "success", + "type": { + "type": "literal", + "value": true + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "success", + "type": { + "type": "literal", + "value": false + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Sends a broadcast message explicitly via REST API.\n\nThis method always uses the REST API endpoint regardless of WebSocket connection state.\nUseful when you want to guarantee REST delivery or when gradually migrating from implicit REST fallback.\n\nPayloads that are `ArrayBuffer` or `ArrayBufferView` (e.g. `Uint8Array`) are sent as\n`application/octet-stream`; all other payloads are JSON-encoded." + } + }, + "@supabase/supabase-js.RealtimeChannel.on": { + "name": "@supabase/supabase-js.RealtimeChannel.on", + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "presence" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "sync" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + }, + "comment": { + "shortText": "Creates an event handler that listens to changes." + }, + "altSignatures": [ + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "presence" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "join" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "name": "RealtimePresenceJoinPayload", + "type": "object", + "properties": [ + { + "name": "currentPresences", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + }, + { + "name": "event" + }, + { + "name": "key", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "newPresences", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "presence" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "leave" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "name": "RealtimePresenceLeavePayload", + "type": "object", + "properties": [ + { + "name": "currentPresences", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + }, + { + "name": "event" + }, + { + "name": "key", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "leftPresences", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "presence" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "*" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "union", + "subTypes": [ + { + "name": "RealtimePresenceJoinPayload", + "type": "object", + "properties": [ + { + "name": "currentPresences", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + }, + { + "name": "event" + }, + { + "name": "key", + "type": "[Circular]" + }, + { + "name": "newPresences", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + } + ] + }, + { + "name": "RealtimePresenceLeavePayload", + "type": "object", + "properties": [ + { + "name": "currentPresences", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + }, + { + "name": "event" + }, + { + "name": "key", + "type": "[Circular]" + }, + { + "name": "leftPresences", + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + } + ] + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "postgres_changes" + } + }, + { + "name": "filter", + "type": { + "name": "RealtimePostgresChangesFilter", + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "*" + }, + "comment": { + "shortText": "The type of database change to listen to." + } + }, + { + "name": "filter", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Receive database changes when filter is matched." + } + }, + { + "name": "schema", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The database schema to listen to." + } + }, + { + "name": "table", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "The database table to listen to." + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "union", + "name": "RealtimePostgresChangesPayload", + "subTypes": [ + { + "type": "nameOnly", + "name": "RealtimePostgresInsertPayload" + }, + { + "type": "nameOnly", + "name": "RealtimePostgresUpdatePayload" + }, + { + "type": "nameOnly", + "name": "RealtimePostgresDeletePayload" + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "postgres_changes" + } + }, + { + "name": "filter", + "type": { + "name": "RealtimePostgresChangesFilter", + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "INSERT" + }, + "comment": { + "shortText": "The type of database change to listen to." + } + }, + { + "name": "filter", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Receive database changes when filter is matched." + } + }, + { + "name": "schema", + "type": "[Circular]", + "comment": { + "shortText": "The database schema to listen to." + } + }, + { + "name": "table", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The database table to listen to." + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "nameOnly", + "name": "RealtimePostgresInsertPayload" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "postgres_changes" + } + }, + { + "name": "filter", + "type": { + "name": "RealtimePostgresChangesFilter", + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "UPDATE" + }, + "comment": { + "shortText": "The type of database change to listen to." + } + }, + { + "name": "filter", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Receive database changes when filter is matched." + } + }, + { + "name": "schema", + "type": "[Circular]", + "comment": { + "shortText": "The database schema to listen to." + } + }, + { + "name": "table", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The database table to listen to." + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "nameOnly", + "name": "RealtimePostgresUpdatePayload" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "postgres_changes" + } + }, + { + "name": "filter", + "type": { + "name": "RealtimePostgresChangesFilter", + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "DELETE" + }, + "comment": { + "shortText": "The type of database change to listen to." + } + }, + { + "name": "filter", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Receive database changes when filter is matched." + } + }, + { + "name": "schema", + "type": "[Circular]", + "comment": { + "shortText": "The database schema to listen to." + } + }, + { + "name": "table", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The database table to listen to." + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "nameOnly", + "name": "RealtimePostgresDeletePayload" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "postgres_changes" + } + }, + { + "name": "filter", + "type": { + "name": "RealtimePostgresChangesFilter", + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "DELETE" + }, + { + "type": "literal", + "value": "*" + }, + { + "type": "literal", + "value": "INSERT" + }, + { + "type": "literal", + "value": "UPDATE" + } + ] + }, + "comment": { + "shortText": "The type of database change to listen to." + } + }, + { + "name": "filter", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Receive database changes when filter is matched." + } + }, + { + "name": "schema", + "type": "[Circular]", + "comment": { + "shortText": "The database schema to listen to." + } + }, + { + "name": "table", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The database table to listen to." + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "union", + "name": "RealtimePostgresChangesPayload", + "subTypes": [ + { + "type": "nameOnly", + "name": "RealtimePostgresInsertPayload" + }, + { + "type": "nameOnly", + "name": "RealtimePostgresUpdatePayload" + }, + { + "type": "nameOnly", + "name": "RealtimePostgresDeletePayload" + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + }, + "comment": { + "shortText": "One of \"broadcast\", \"presence\", or \"postgres_changes\"." + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "comment": { + "shortText": "Custom object specific to the Realtime feature detailing which payloads to receive." + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "meta", + "type": { + "type": "object", + "properties": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "replayed", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + } + ] + }, + "isOptional": true + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "Function to be invoked when event handler is triggered." + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "meta", + "type": { + "type": "object", + "properties": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "replayed", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + } + ] + }, + "isOptional": true + }, + { + "name": "payload", + "type": { + "type": "nameOnly", + "name": "T" + } + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "*", + "name": "ALL" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": "[Circular]" + }, + { + "name": "payload", + "type": { + "type": "nameOnly", + "name": "RealtimeBroadcastPayload" + } + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "INSERT", + "name": "INSERT" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": "[Circular]" + }, + { + "name": "payload", + "type": { + "type": "nameOnly", + "name": "RealtimeBroadcastInsertPayload" + } + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "UPDATE", + "name": "UPDATE" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": "[Circular]" + }, + { + "name": "payload", + "type": { + "type": "nameOnly", + "name": "RealtimeBroadcastUpdatePayload" + } + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + }, + { + "name": "filter", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "literal", + "value": "DELETE", + "name": "DELETE" + } + } + ] + } + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": "[Circular]" + }, + { + "name": "payload", + "type": { + "type": "nameOnly", + "name": "RealtimeBroadcastDeletePayload" + } + }, + { + "name": "type", + "type": { + "type": "literal", + "value": "broadcast" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + { + "params": [ + { + "name": "type", + "type": { + "type": "literal", + "value": "system" + } + }, + { + "name": "filter" + }, + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "payload", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + } + ] + }, + "@supabase/supabase-js.RealtimeChannel.presenceState": { + "name": "@supabase/supabase-js.RealtimeChannel.presenceState", + "params": [], + "ret": { + "type": { + "name": "RealtimePresenceState", + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "Presence" + } + } + } + }, + "comment": { + "shortText": "Returns the current presence state for this channel.\n\nThe shape is a map keyed by presence key (for example a user id) where each entry contains the\ntracked metadata for that user." + } + }, + "@supabase/supabase-js.RealtimeChannel.send": { + "name": "@supabase/supabase-js.RealtimeChannel.send", + "params": [ + { + "name": "args", + "type": { + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The name of the event being sent" + } + }, + { + "name": "payload", + "type": { + "type": "intrinsic", + "name": "any" + }, + "isOptional": true, + "comment": { + "shortText": "Payload to be sent" + } + }, + { + "name": "type", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "broadcast" + }, + { + "type": "literal", + "value": "presence" + }, + { + "type": "literal", + "value": "postgres_changes" + } + ] + }, + "comment": { + "shortText": "The type of event to send" + } + } + ] + }, + "comment": { + "shortText": "Arguments to send to channel" + } + }, + { + "name": "opts", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + "isOptional": true, + "comment": { + "shortText": "Options to be used during the send process" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "RealtimeChannelSendResponse", + "subTypes": [ + { + "type": "literal", + "value": "ok" + }, + { + "type": "literal", + "value": "timed out" + }, + { + "type": "literal", + "value": "error" + }, + null + ] + } + } + }, + "comment": { + "shortText": "Sends a message into the channel.", + "text": "- When using REST you don't need to subscribe to the channel\n- REST calls are only available from 2.37.0 onwards\n- If you create a channel only to send a REST broadcast, remove it from\n the client when the send completes", + "examples": [ + { + "id": "send-a-message-via-websocket", + "name": "Send a message via websocket", + "code": "```js\nconst channel = supabase.channel('room1')\n\nchannel.subscribe((status) => {\n if (status === 'SUBSCRIBED') {\n channel.send({\n type: 'broadcast',\n event: 'cursor-pos',\n payload: { x: Math.random(), y: Math.random() },\n })\n }\n})\n```", + "response": "```js\nok | timed out | error\n```" + }, + { + "id": "send-a-message-via-rest", + "name": "Send a message via REST", + "code": "```js\nconst channel = supabase.channel('room1')\n\ntry {\n await channel.httpSend('cursor-pos', { x: Math.random(), y: Math.random() })\n} finally {\n await supabase.removeChannel(channel)\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.RealtimeChannel.subscribe": { + "name": "@supabase/supabase-js.RealtimeChannel.subscribe", + "params": [ + { + "name": "callback", + "type": { + "type": "function", + "params": [ + { + "name": "status", + "type": { + "type": "nameOnly", + "name": "REALTIME_SUBSCRIBE_STATES" + } + }, + { + "name": "err", + "type": { + "type": "nameOnly", + "name": "Error" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + }, + "isOptional": true + }, + { + "name": "timeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + }, + "comment": { + "shortText": "Subscribe registers your client with the server.\n\nThe optional `callback` receives a `status` and, on failure, an `err` argument.\nLog the full `err` so its `cause`, `name`, and any structured fields aren't hidden\nbehind `err.message`.", + "examples": [ + { + "id": "handling-errors", + "name": "Handling errors", + "code": "```js\nsupabase.channel('room1').subscribe((status, err) => {\n if (status === 'CHANNEL_ERROR' || status === 'TIMED_OUT') {\n // Log the full error: its `cause` often holds the underlying reason.\n console.error(status, err)\n }\n})\n```" + } + ] + } + }, + "@supabase/supabase-js.RealtimeChannel.teardown": { + "name": "@supabase/supabase-js.RealtimeChannel.teardown", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Destroys and stops related timers." + } + }, + "@supabase/supabase-js.RealtimeChannel.track": { + "name": "@supabase/supabase-js.RealtimeChannel.track", + "params": [ + { + "name": "payload", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + } + }, + { + "name": "opts", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "RealtimeChannelSendResponse", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + } + }, + "comment": { + "shortText": "Sends the supplied payload to the presence tracker so other subscribers can see that this\nclient is online. Use `untrack` to stop broadcasting presence for the same key." + } + }, + "@supabase/supabase-js.RealtimeChannel.unsubscribe": { + "name": "@supabase/supabase-js.RealtimeChannel.unsubscribe", + "params": [ + { + "name": "timeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "RealtimeChannelSendResponse", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + } + }, + "comment": { + "shortText": "Leaves the channel.\n\nUnsubscribes from server events, and instructs channel to terminate on server.\nTriggers onClose() hooks.\n\nTo receive leave acknowledgements, use the a `receive` hook to bind to the server ack, ie:\nchannel.unsubscribe().receive(\"ok\", () => alert(\"left!\") )" + } + }, + "@supabase/supabase-js.RealtimeChannel.untrack": { + "name": "@supabase/supabase-js.RealtimeChannel.untrack", + "params": [ + { + "name": "opts", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "RealtimeChannelSendResponse", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + } + }, + "comment": { + "shortText": "Removes the current presence state for this client." + } + }, + "@supabase/supabase-js.RealtimeChannel.updateJoinPayload": { + "name": "@supabase/supabase-js.RealtimeChannel.updateJoinPayload", + "params": [ + { + "name": "payload", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Updates the payload that will be sent the next time the channel joins (reconnects).\nUseful for rotating access tokens or updating config without re-creating the channel." + } + }, + "@supabase/supabase-js.RealtimeClient.constructor": { + "name": "@supabase/supabase-js.RealtimeClient.constructor", + "params": [ + { + "name": "endPoint", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The string WebSocket endpoint, ie, \"ws://example.com/socket\", \"wss://example.com\", \"/socket\" (inherited host & protocol)" + } + }, + { + "name": "options", + "type": { + "name": "RealtimeClientOptions", + "type": "object", + "properties": [ + { + "name": "accessToken", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "literal", + "value": null + } + ] + } + } + } + }, + "isOptional": true + }, + { + "name": "decode", + "type": { + "type": "nameOnly", + "name": "Decode" + }, + "isOptional": true + }, + { + "name": "disconnectOnEmptyChannelsAfterMs", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "encode", + "type": { + "type": "nameOnly", + "name": "Encode" + }, + "isOptional": true + }, + { + "name": "fetch", + "type": { + "type": "nameOnly", + "name": "Fetch" + }, + "isOptional": true + }, + { + "name": "headers", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true + }, + { + "name": "heartbeatCallback", + "type": { + "type": "function", + "params": [ + { + "name": "status", + "type": { + "type": "nameOnly", + "name": "HeartbeatStatus" + } + }, + { + "name": "latency", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + }, + "isOptional": true + }, + { + "name": "heartbeatIntervalMs", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "log_level", + "type": { + "type": "nameOnly", + "name": "LogLevel" + }, + "isOptional": true + }, + { + "name": "logger", + "type": { + "type": "function", + "params": [ + { + "name": "kind", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "msg", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "any" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + } + }, + "isOptional": true + }, + { + "name": "logLevel", + "type": { + "type": "nameOnly", + "name": "LogLevel" + }, + "isOptional": true + }, + { + "name": "params", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + "isOptional": true + }, + { + "name": "reconnectAfterMs", + "type": { + "type": "function", + "params": [ + { + "name": "tries", + "type": { + "type": "intrinsic", + "name": "number" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "number" + } + } + }, + "isOptional": true + }, + { + "name": "sessionStorage", + "type": { + "type": "nameOnly", + "name": "Storage" + }, + "isOptional": true, + "comment": { + "shortText": "Storage compatible object used by the underlying socket for longpoll fallback history.\nProvide a custom implementation in environments where reading `globalThis.sessionStorage`\nthrows (sandboxed iframes, in-app webviews, \"block third-party storage\" privacy modes).\nDefaults to `globalThis.sessionStorage` when accessible, otherwise an in-memory store." + } + }, + { + "name": "timeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "transport", + "type": { + "type": "object", + "name": "WebSocketLikeConstructor", + "properties": [] + }, + "isOptional": true + }, + { + "name": "vsn", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "worker", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true + }, + { + "name": "workerUrl", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeClient" + } + }, + "comment": { + "shortText": "Initializes the Socket.", + "examples": [ + { + "id": "using-supabase-js-recommended", + "name": "Using supabase-js (recommended)", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst channel = supabase.channel('room1')\nchannel\n .on('broadcast', { event: 'cursor-pos' }, (payload) => console.log(payload))\n .subscribe()\n```" + }, + { + "id": "standalone-import-for-bundle-sensitive-environments", + "name": "Standalone import for bundle-sensitive environments", + "code": "```ts\nimport RealtimeClient from '@supabase/realtime-js'\n\nconst client = new RealtimeClient('https://xyzcompany.supabase.co/realtime/v1', {\n params: { apikey: 'your-publishable-key' },\n})\nclient.connect()\n```" + } + ] + } + }, + "@supabase/supabase-js.RealtimeClient.channel": { + "name": "@supabase/supabase-js.RealtimeClient.channel", + "params": [ + { + "name": "topic", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "params", + "type": { + "name": "RealtimeChannelOptions", + "type": "object", + "properties": [ + { + "name": "config", + "type": { + "type": "object", + "properties": [ + { + "name": "broadcast", + "type": { + "type": "object", + "properties": [ + { + "name": "ack", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "replay", + "type": { + "type": "nameOnly", + "name": "ReplayOption" + }, + "isOptional": true + }, + { + "name": "self", + "type": "[Circular]", + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "self option enables client to receive message it broadcast\nack option instructs server to acknowledge that broadcast message was received\nreplay option instructs server to replay broadcast messages" + } + }, + { + "name": "presence", + "type": { + "type": "object", + "properties": [ + { + "name": "enabled", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "key", + "type": "[Circular]", + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "key option is used to track presence payload across clients" + } + }, + { + "name": "private", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "defines if the channel is private or not and if RLS policies will be used to check data" + } + } + ] + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + }, + "comment": { + "shortText": "Creates (or reuses) a RealtimeChannel for the provided topic.\n\nTopics are automatically prefixed with `realtime:` to match the Realtime service.\nIf a channel with the same topic already exists it will be returned instead of creating\na duplicate connection." + } + }, + "@supabase/supabase-js.RealtimeClient.connect": { + "name": "@supabase/supabase-js.RealtimeClient.connect", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Connects the socket, unless already connected." + } + }, + "@supabase/supabase-js.RealtimeClient.connectionState": { + "name": "@supabase/supabase-js.RealtimeClient.connectionState", + "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "ConnectionState" + } + }, + "comment": { + "shortText": "Returns the current state of the socket." + } + }, + "@supabase/supabase-js.RealtimeClient.disconnect": { + "name": "@supabase/supabase-js.RealtimeClient.disconnect", + "params": [ + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "A numeric status code to send on disconnect." + } + }, + { + "name": "reason", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "A custom reason for the disconnect." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "timeout" + }, + { + "type": "literal", + "value": "ok" + } + ] + } + } + }, + "comment": { + "shortText": "Disconnects the socket." + } + }, + "@supabase/supabase-js.RealtimeClient.endpointURL": { + "name": "@supabase/supabase-js.RealtimeClient.endpointURL", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "string" + } + }, + "comment": { + "shortText": "Returns the URL of the websocket." + } + }, + "@supabase/supabase-js.RealtimeClient.getChannels": { + "name": "@supabase/supabase-js.RealtimeClient.getChannels", + "params": [], + "ret": { + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + "comment": { + "shortText": "Returns all created channels" + } + }, + "@supabase/supabase-js.RealtimeClient.isConnected": { + "name": "@supabase/supabase-js.RealtimeClient.isConnected", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "boolean" + } + }, + "comment": { + "shortText": "Returns `true` is the connection is open." + } + }, + "@supabase/supabase-js.RealtimeClient.isConnecting": { + "name": "@supabase/supabase-js.RealtimeClient.isConnecting", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "boolean" + } + }, + "comment": { + "shortText": "Returns `true` if the connection is currently connecting." + } + }, + "@supabase/supabase-js.RealtimeClient.isDisconnecting": { + "name": "@supabase/supabase-js.RealtimeClient.isDisconnecting", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "boolean" + } + }, + "comment": { + "shortText": "Returns `true` if the connection is currently disconnecting." + } + }, + "@supabase/supabase-js.RealtimeClient.log": { + "name": "@supabase/supabase-js.RealtimeClient.log", + "params": [ + { + "name": "kind", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "msg", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "data", + "type": { + "type": "intrinsic", + "name": "any" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Logs the message.\n\nFor customized logging, `this.logger` can be overridden in Client constructor." + } + }, + "@supabase/supabase-js.RealtimeClient.onHeartbeat": { + "name": "@supabase/supabase-js.RealtimeClient.onHeartbeat", + "params": [ + { + "name": "callback", + "type": { + "type": "nameOnly", + "name": "HeartbeatCallback" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Sets a callback that receives lifecycle events for internal heartbeat messages.\nUseful for instrumenting connection health (e.g. sent/ok/timeout/disconnected)." + } + }, + "@supabase/supabase-js.RealtimeClient.push": { + "name": "@supabase/supabase-js.RealtimeClient.push", + "params": [ + { + "name": "data", + "type": { + "name": "RealtimeMessage", + "type": "object", + "properties": [ + { + "name": "event", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "join_ref", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "payload", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "ref", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "topic", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Push out a message if the socket is connected.\n\nIf the socket is not connected, the message gets enqueued within a local buffer, and sent out when a connection is next established." + } + }, + "@supabase/supabase-js.RealtimeClient.removeAllChannels": { + "name": "@supabase/supabase-js.RealtimeClient.removeAllChannels", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "array", + "elemType": { + "type": "union", + "name": "RealtimeRemoveChannelResponse", + "subTypes": [ + { + "type": "literal", + "value": "ok" + }, + { + "type": "literal", + "value": "timed out" + }, + { + "type": "literal", + "value": "error" + }, + null + ] + } + } + } + }, + "comment": { + "shortText": "Unsubscribes, removes and tears down all channels" + } + }, + "@supabase/supabase-js.RealtimeClient.removeChannel": { + "name": "@supabase/supabase-js.RealtimeClient.removeChannel", + "params": [ + { + "name": "channel", + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + }, + "comment": { + "shortText": "A RealtimeChannel instance" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "RealtimeRemoveChannelResponse", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + } + }, + "comment": { + "shortText": "Unsubscribes, removes and tears down a single channel" + } + }, + "@supabase/supabase-js.RealtimeClient.sendHeartbeat": { + "name": "@supabase/supabase-js.RealtimeClient.sendHeartbeat", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "Sends a heartbeat message if the socket is connected." + } + }, + "@supabase/supabase-js.RealtimeClient.setAuth": { + "name": "@supabase/supabase-js.RealtimeClient.setAuth", + "params": [ + { + "name": "token", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "A JWT string to override the token set on the client." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "intrinsic", + "name": "void" + } + } + }, + "comment": { + "shortText": "Sets the JWT access token used for channel subscription authorization and Realtime RLS.\n\nIf param is null it will use the `accessToken` callback function or the token set on the client.\n\nOn callback used, it will set the value of the token internal to the client.\n\nWhen a token is explicitly provided, it will be preserved across channel operations\n(including removeChannel and resubscribe). The `accessToken` callback will not be\ninvoked until `setAuth()` is called without arguments.", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\nSetting the authorization header\n// Use a manual token (preserved across resubscribes, ignores accessToken callback)\nclient.realtime.setAuth('my-custom-jwt')\n\n// Switch back to using the accessToken callback\nclient.realtime.setAuth()\n```" + } + ] + } + }, + "@supabase/supabase-js.RealtimePresence.constructor": { + "name": "@supabase/supabase-js.RealtimePresence.constructor", + "params": [ + { + "name": "channel", + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + }, + "comment": { + "shortText": "The realtime channel to bind to." + } + }, + { + "name": "opts", + "type": { + "type": "nameOnly", + "name": "RealtimePresenceOptions" + }, + "isOptional": true, + "comment": { + "shortText": "Optional custom event names, e.g. `{ events: { state: 'state', diff: 'diff' } }`." + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimePresence" + } + }, + "comment": { + "shortText": "Creates a Presence helper that keeps the local presence state in sync with the server.", + "examples": [ + { + "id": "example-for-a-presence-channel", + "name": "Example for a presence channel", + "code": "```ts\nconst presence = new RealtimePresence(channel)\n\nchannel.on('presence', ({ event, key }) => {\n console.log(`Presence ${event} on ${key}`)\n})\n```" + } + ] + } + }, + "@supabase/supabase-js.StorageApiError.constructor": { + "name": "@supabase/supabase-js.StorageApiError.constructor", + "params": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "statusCode", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "namespace", + "type": { + "type": "nameOnly", + "name": "ErrorNamespace" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "StorageApiError" + } + } + }, + "@supabase/supabase-js.StorageApiError.toJSON": { + "name": "@supabase/supabase-js.StorageApiError.toJSON", + "params": [], + "ret": { + "type": { + "type": "object", + "properties": [ + { + "name": "message", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + }, + { + "name": "statusCode", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ] + } + } + }, + "@supabase/supabase-js.SupabaseClient.constructor": { + "name": "@supabase/supabase-js.SupabaseClient.constructor", + "params": [ + { + "name": "supabaseUrl", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The unique Supabase URL which is supplied when you create a new project in your project dashboard." + } + }, + { + "name": "supabaseKey", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The unique Supabase Key which is supplied when you create a new project in your project dashboard." + } + }, + { + "name": "options", + "type": { + "name": "SupabaseClientOptions", + "type": "object", + "properties": [ + { + "name": "accessToken", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "literal", + "value": null + } + ] + } + } + } + }, + "isOptional": true, + "comment": { + "shortText": "Optional function for using a third-party authentication system with\nSupabase. The function should return an access token or ID token (JWT) by\nobtaining it from the third-party auth SDK. Note that this\nfunction may be called concurrently and many times. Use memoization and\nlocking techniques if this is not supported by the SDKs.\n\nWhen set, the `auth` namespace of the Supabase client cannot be used.\nCreate another client if you wish to use Supabase Auth and third-party\nauthentications concurrently in the same application." + } + }, + { + "name": "auth", + "type": { + "type": "object", + "properties": [ + { + "name": "autoRefreshToken", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Automatically refreshes the token for logged-in users. Defaults to true." + } + }, + { + "name": "debug", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['debug']" + }, + "isOptional": true, + "comment": { + "shortText": "If debug messages for authentication client are emitted. Can be used to inspect the behavior of the library." + } + }, + { + "name": "detectSessionInUrl", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "boolean" + }, + { + "type": "function", + "params": [ + { + "name": "url", + "type": { + "type": "nameOnly", + "name": "URL" + } + }, + { + "name": "params", + "type": { + "type": "index signature", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "boolean" + } + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Detect a session from the URL. Used for OAuth login callbacks. Defaults to true.\n\nCan be set to a function to provide custom logic for determining if a URL contains\na Supabase auth callback. The function receives the current URL and parsed parameters,\nand should return true if the URL should be processed as a Supabase auth callback.\n\nThis is useful when your app uses other OAuth providers (e.g., Facebook Login) that\nalso return access_token in the URL fragment, which would otherwise be incorrectly\nintercepted by Supabase Auth.", + "examples": [ + { + "id": "with-custom-detection-logic", + "name": "With custom detection logic", + "code": "```ts\ndetectSessionInUrl: (url, params) => {\n // Ignore Facebook OAuth redirects\n if (url.pathname === '/facebook/redirect') return false\n // Use default detection for other URLs\n return Boolean(params.access_token || params.error_description)\n}\n```" + } + ] + } + }, + { + "name": "experimental", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['experimental']" + }, + "isOptional": true, + "comment": { + "shortText": "Opt-in flags for experimental features. These APIs may change without\nnotice and are disabled by default.", + "tags": [ + { + "tag": "experimental", + "text": "" + } + ] + } + }, + { + "name": "flowType", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['flowType']" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth flow to use - defaults to implicit flow. PKCE is recommended for mobile and server-side applications." + } + }, + { + "name": "lock", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['lock']" + }, + "isOptional": true, + "comment": { + "shortText": "Provide your own locking mechanism based on the environment. By default\nthe auth client coordinates refreshes itself and the server resolves\ncross-tab races. Passing a custom `lock` opts into a legacy path that\nwraps every auth operation in your supplied lock." + } + }, + { + "name": "lockAcquireTimeout", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['lockAcquireTimeout']" + }, + "isOptional": true, + "comment": { + "shortText": "Maximum time in milliseconds to wait for acquiring the custom lock\nsupplied via `lock`. Only consulted when a custom `lock` is passed." + } + }, + { + "name": "persistSession", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether to persist a logged-in session to storage. Defaults to true." + } + }, + { + "name": "skipAutoInitialize", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['skipAutoInitialize']" + }, + "isOptional": true, + "comment": { + "shortText": "If true, skips automatic initialization in the auth client constructor.\nUseful for SSR contexts where initialization timing must be controlled to\nprevent race conditions with HTTP response generation." + } + }, + { + "name": "storage", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['storage']" + }, + "isOptional": true, + "comment": { + "shortText": "A storage provider. Used to store the logged-in session." + } + }, + { + "name": "storageKey", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Optional key name used for storing tokens in local storage." + } + }, + { + "name": "throwOnError", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['throwOnError']" + }, + "isOptional": true, + "comment": { + "shortText": "If there is an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response." + } + }, + { + "name": "userStorage", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['userStorage']" + }, + "isOptional": true, + "comment": { + "shortText": "A storage provider to store the user profile separately from the session.\nUseful when you need to store the session information in cookies,\nwithout bloating the data with the redundant user object.", + "tags": [ + { + "tag": "experimental", + "text": "" + } + ] + } + } + ] + }, + "isOptional": true + }, + { + "name": "db", + "type": { + "type": "object", + "properties": [ + { + "name": "schema", + "type": { + "type": "nameOnly", + "name": "@supabase/supabase-js.default.SchemaName" + }, + "isOptional": true + }, + { + "name": "timeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "Optional timeout in milliseconds for PostgREST requests.\nWhen set, requests will automatically abort after this duration to prevent indefinite hangs.", + "examples": [ + { + "id": "with-timeout", + "name": "With timeout", + "code": "```ts\nconst supabase = createClient(url, key, {\n db: { timeout: 30000 } // 30 second timeout\n})\n```" + } + ] + } + }, + { + "name": "urlLengthLimit", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true, + "comment": { + "shortText": "Maximum URL length in characters before warnings/errors are triggered.\nDefaults to 8000 characters. Used to provide helpful hints when URLs\nexceed server limits.", + "examples": [ + { + "id": "with-custom-url-length-limit", + "name": "With custom URL length limit", + "code": "```ts\nconst supabase = createClient(url, key, {\n db: { urlLengthLimit: 10000 } // Custom limit\n})\n```" + } + ] + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The Postgres schema which your tables belong to. Must be on the list of exposed schemas in Supabase. Defaults to `public`." + } + }, + { + "name": "global", + "type": { + "type": "object", + "properties": [ + { + "name": "fetch", + "type": { + "type": "nameOnly", + "name": "Fetch" + }, + "isOptional": true, + "comment": { + "shortText": "A custom `fetch` implementation." + } + }, + { + "name": "headers", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Optional headers for initializing the client." + } + } + ] + }, + "isOptional": true + }, + { + "name": "realtime", + "type": { + "name": "RealtimeClientOptions", + "type": "object", + "properties": [ + { + "name": "accessToken", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + } + } + } + }, + "isOptional": true + }, + { + "name": "decode", + "type": { + "type": "nameOnly", + "name": "Decode" + }, + "isOptional": true + }, + { + "name": "disconnectOnEmptyChannelsAfterMs", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "encode", + "type": { + "type": "nameOnly", + "name": "Encode" + }, + "isOptional": true + }, + { + "name": "fetch", + "type": { + "type": "nameOnly", + "name": "Fetch" + }, + "isOptional": true + }, + { + "name": "headers", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "heartbeatCallback", + "type": { + "type": "function", + "params": [ + { + "name": "status", + "type": { + "type": "nameOnly", + "name": "HeartbeatStatus" + } + }, + { + "name": "latency", + "type": "[Circular]", + "isOptional": true + } + ], + "ret": { + "type": "[Circular]" + } + }, + "isOptional": true + }, + { + "name": "heartbeatIntervalMs", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "log_level", + "type": { + "type": "nameOnly", + "name": "LogLevel" + }, + "isOptional": true + }, + { + "name": "logger", + "type": { + "type": "function", + "params": [ + { + "name": "kind", + "type": "[Circular]" + }, + { + "name": "msg", + "type": "[Circular]" + }, + { + "name": "data", + "type": "[Circular]", + "isOptional": true + } + ], + "ret": { + "type": "[Circular]" + } + }, + "isOptional": true + }, + { + "name": "logLevel", + "type": { + "type": "nameOnly", + "name": "LogLevel" + }, + "isOptional": true + }, + { + "name": "params", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "reconnectAfterMs", + "type": { + "type": "function", + "params": [ + { + "name": "tries", + "type": "[Circular]" + } + ], + "ret": { + "type": "[Circular]" + } + }, + "isOptional": true + }, + { + "name": "sessionStorage", + "type": { + "type": "nameOnly", + "name": "Storage" + }, + "isOptional": true, + "comment": { + "shortText": "Storage compatible object used by the underlying socket for longpoll fallback history.\nProvide a custom implementation in environments where reading `globalThis.sessionStorage`\nthrows (sandboxed iframes, in-app webviews, \"block third-party storage\" privacy modes).\nDefaults to `globalThis.sessionStorage` when accessible, otherwise an in-memory store." + } + }, + { + "name": "timeout", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "transport", + "type": { + "type": "object", + "name": "WebSocketLikeConstructor", + "properties": [] + }, + "isOptional": true + }, + { + "name": "vsn", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "worker", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "workerUrl", + "type": "[Circular]", + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Options passed to the realtime-js instance" + } + }, + { + "name": "storage", + "type": { + "type": "nameOnly", + "name": "StorageClientOptions" + }, + "isOptional": true + }, + { + "name": "tracePropagation", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "TracePropagationOptions", + "properties": [ + { + "name": "enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Enable trace propagation. Disabled by default.\n\nWhen enabled, automatically detects and propagates active trace context\nfrom the OpenTelemetry API to outgoing Supabase requests. Trace context\nis only propagated to Supabase domains (`*.supabase.co`, `*.supabase.in`,\n`localhost`) for security — third-party hosts never receive trace headers.", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\nconst supabase = createClient(url, key, {\n tracePropagation: { enabled: true },\n})\n```" + } + ] + } + }, + { + "name": "respectSamplingDecision", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Respect upstream sampling decisions.\n\nWhen true (the default), trace context is not propagated if the upstream\ntrace indicates non-sampling (sampled flag = `0` in the `traceparent`\nheader). This avoids overhead when traces are being recorded but dropped.\n\nSet to `false` to always propagate, regardless of the sampling decision\n— useful when you want every Supabase request tagged with a `trace_id`\nfor log correlation, even if the trace itself will not be exported.", + "examples": [ + { + "id": "always-propagate-ignore-sampling", + "name": "Always propagate, ignore sampling", + "code": "```ts\nconst supabase = createClient(url, key, {\n tracePropagation: { enabled: true, respectSamplingDecision: false },\n})\n```" + } + ] + } + } + ] + }, + { + "type": "intrinsic", + "name": "boolean" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Enable OpenTelemetry / W3C trace context propagation to Supabase services.\n\nDisabled by default. Pass `true` for the common case (auto-detect an\nactive OpenTelemetry context and inject `traceparent` / `tracestate` /\n`baggage` headers) or an object for fine-grained control.\n\nRequires `@opentelemetry/api` to be installed in your application; if\nnot present, the SDK silently no-ops. Trace headers are only attached\nto requests targeting Supabase domains, so third-party hosts called\nthrough a custom `fetch` are never tagged.\n\nThe resulting `trace_id` appears in Supabase logs (API Gateway, Edge\nFunctions), letting you correlate client-side spans with server-side\nlog entries — including logs forwarded via Log Drains.", + "examples": [ + { + "id": "shorthand-opt-in-with-defaults", + "name": "Shorthand — opt in with defaults", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient(url, key, { tracePropagation: true })\n```" + }, + { + "id": "with-an-active-opentelemetry-span", + "name": "With an active OpenTelemetry span", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\nimport { trace } from '@opentelemetry/api'\n\nconst supabase = createClient(url, key, { tracePropagation: true })\nconst tracer = trace.getTracer('my-app')\n\nawait tracer.startActiveSpan('fetch-users', async (span) => {\n // Request carries the active trace context.\n const { data, error } = await supabase.from('users').select('*')\n span.end()\n})\n```" + }, + { + "id": "advanced-always-propagate-even-for-non-sampled-traces", + "name": "Advanced — always propagate, even for non-sampled traces", + "code": "```ts\nconst supabase = createClient(url, key, {\n tracePropagation: { enabled: true, respectSamplingDecision: false },\n})\n```" + } + ] + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "SupabaseClient" + } + }, + "comment": { + "shortText": "Create a new client for use in the browser.", + "examples": [ + { + "id": "creating-a-client", + "name": "Creating a client", + "code": "```js\nimport { createClient } from '@supabase/supabase-js'\n\n// Create a single supabase client for interacting with your database\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\n```" + }, + { + "id": "with-a-custom-domain", + "name": "With a custom domain", + "code": "```js\nimport { createClient } from '@supabase/supabase-js'\n\n// Use a custom domain as the supabase URL\nconst supabase = createClient('https://my-custom-domain.com', 'your-publishable-key')\n```" + }, + { + "id": "with-additional-parameters", + "name": "With additional parameters", + "code": "```js\nimport { createClient } from '@supabase/supabase-js'\n\nconst options = {\n db: {\n schema: 'public',\n },\n auth: {\n autoRefreshToken: true,\n persistSession: true,\n detectSessionInUrl: true\n },\n global: {\n headers: { 'x-my-custom-header': 'my-app-name' },\n },\n}\nconst supabase = createClient(\"https://xyzcompany.supabase.co\", \"your-publishable-key\", options)\n```" + }, + { + "id": "with-custom-schemas", + "name": "With custom schemas", + "code": "```js\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key', {\n // Provide a custom schema. Defaults to \"public\".\n db: { schema: 'other_schema' }\n})\n```", + "description": "By default the API server points to the `public` schema. You can enable other database schemas within the Dashboard.\nGo to [Settings > API > Exposed schemas](/dashboard/project/_/settings/api) and add the schema which you want to expose to the API.\n\nNote: each client connection can only access a single schema, so the code above can access the `other_schema` schema but cannot access the `public` schema." + }, + { + "id": "custom-fetch-implementation", + "name": "Custom fetch implementation", + "code": "```js\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key', {\n global: { fetch: fetch.bind(globalThis) }\n})\n```", + "description": "`supabase-js` uses the [`cross-fetch`](https://www.npmjs.com/package/cross-fetch) library to make HTTP requests,\nbut an alternative `fetch` implementation can be provided as an option.\nThis is most useful in environments where `cross-fetch` is not compatible (for instance Cloudflare Workers)." + }, + { + "id": "react-native-options-with-asyncstorage", + "name": "React Native options with AsyncStorage", + "code": "```js\nimport 'react-native-url-polyfill/auto'\nimport { createClient } from '@supabase/supabase-js'\nimport AsyncStorage from \"@react-native-async-storage/async-storage\";\n\nconst supabase = createClient(\"https://xyzcompany.supabase.co\", \"your-publishable-key\", {\n auth: {\n storage: AsyncStorage,\n autoRefreshToken: true,\n persistSession: true,\n detectSessionInUrl: false,\n },\n});\n```", + "description": "For React Native we recommend using `AsyncStorage` as the storage implementation for Supabase Auth." + }, + { + "id": "react-native-options-with-expo-securestore", + "name": "React Native options with Expo SecureStore", + "code": "```ts\nimport 'react-native-url-polyfill/auto'\nimport { createClient } from '@supabase/supabase-js'\nimport AsyncStorage from '@react-native-async-storage/async-storage';\nimport * as SecureStore from 'expo-secure-store';\nimport * as aesjs from 'aes-js';\nimport 'react-native-get-random-values';\n\n// As Expo's SecureStore does not support values larger than 2048\n// bytes, an AES-256 key is generated and stored in SecureStore, while\n// it is used to encrypt/decrypt values stored in AsyncStorage.\nclass LargeSecureStore {\n private async _encrypt(key: string, value: string) {\n const encryptionKey = crypto.getRandomValues(new Uint8Array(256 / 8));\n\n const cipher = new aesjs.ModeOfOperation.ctr(encryptionKey, new aesjs.Counter(1));\n const encryptedBytes = cipher.encrypt(aesjs.utils.utf8.toBytes(value));\n\n await SecureStore.setItemAsync(key, aesjs.utils.hex.fromBytes(encryptionKey));\n\n return aesjs.utils.hex.fromBytes(encryptedBytes);\n }\n\n private async _decrypt(key: string, value: string) {\n const encryptionKeyHex = await SecureStore.getItemAsync(key);\n if (!encryptionKeyHex) {\n return encryptionKeyHex;\n }\n\n const cipher = new aesjs.ModeOfOperation.ctr(aesjs.utils.hex.toBytes(encryptionKeyHex), new aesjs.Counter(1));\n const decryptedBytes = cipher.decrypt(aesjs.utils.hex.toBytes(value));\n\n return aesjs.utils.utf8.fromBytes(decryptedBytes);\n }\n\n async getItem(key: string) {\n const encrypted = await AsyncStorage.getItem(key);\n if (!encrypted) { return encrypted; }\n\n return await this._decrypt(key, encrypted);\n }\n\n async removeItem(key: string) {\n await AsyncStorage.removeItem(key);\n await SecureStore.deleteItemAsync(key);\n }\n\n async setItem(key: string, value: string) {\n const encrypted = await this._encrypt(key, value);\n\n await AsyncStorage.setItem(key, encrypted);\n }\n}\n\nconst supabase = createClient(\"https://xyzcompany.supabase.co\", \"your-publishable-key\", {\n auth: {\n storage: new LargeSecureStore(),\n autoRefreshToken: true,\n persistSession: true,\n detectSessionInUrl: false,\n },\n});\n```", + "description": "If you wish to encrypt the user's session information, you can use `aes-js` and store the encryption key in Expo SecureStore.\nThe `aes-js` library, a reputable JavaScript-only implementation of the AES encryption algorithm in CTR mode.\nA new 256-bit encryption key is generated using the `react-native-get-random-values` library.\nThis key is stored inside Expo's SecureStore, while the value is encrypted and placed inside AsyncStorage.\n\nPlease make sure that:\n- You keep the `expo-secure-store`, `aes-js` and `react-native-get-random-values` libraries up-to-date.\n- Choose the correct [`SecureStoreOptions`](https://docs.expo.dev/versions/latest/sdk/securestore/#securestoreoptions) for your app's needs.\n E.g. [`SecureStore.WHEN_UNLOCKED`](https://docs.expo.dev/versions/latest/sdk/securestore/#securestorewhen_unlocked) regulates when the data can be accessed.\n- Carefully consider optimizations or other modifications to the above example, as those can lead to introducing subtle security vulnerabilities." + }, + { + "id": "with-a-database-query", + "name": "With a database query", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\n\nconst { data } = await supabase.from('profiles').select('*')\n```" + }, + { + "id": "with-opentelemetry-tracing", + "name": "With OpenTelemetry tracing", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\nimport { trace } from '@opentelemetry/api'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key', {\n tracePropagation: true,\n})\n\nconst tracer = trace.getTracer('my-app')\n\nawait tracer.startActiveSpan('fetch-users', async (span) => {\n // Outgoing request carries the active trace context.\n const { data, error } = await supabase.from('users').select('*')\n span.end()\n})\n```", + "description": "Opt in to W3C trace context propagation so the `trace_id` from your\nclient-side spans is attached to Supabase requests and appears in API\nGateway and Edge Function logs. Requires `@opentelemetry/api` to be\ninstalled in your application. See [Tracing with the JS SDK](https://supabase.com/docs/guides/telemetry/client-side-tracing)." + } + ] + } + }, + "@supabase/supabase-js.SupabaseClient.channel": { + "name": "@supabase/supabase-js.SupabaseClient.channel", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The name of the Realtime channel." + } + }, + { + "name": "opts", + "type": { + "name": "RealtimeChannelOptions", + "type": "object", + "properties": [ + { + "name": "config", + "type": { + "type": "object", + "properties": [ + { + "name": "broadcast", + "type": { + "type": "object", + "properties": [ + { + "name": "ack", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "replay", + "type": { + "type": "nameOnly", + "name": "ReplayOption" + }, + "isOptional": true + }, + { + "name": "self", + "type": "[Circular]", + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "self option enables client to receive message it broadcast\nack option instructs server to acknowledge that broadcast message was received\nreplay option instructs server to replay broadcast messages" + } + }, + { + "name": "presence", + "type": { + "type": "object", + "properties": [ + { + "name": "enabled", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "key", + "type": "[Circular]", + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "key option is used to track presence payload across clients" + } + }, + { + "name": "private", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "defines if the channel is private or not and if RLS policies will be used to check data" + } + } + ] + } + } + ] + }, + "comment": { + "shortText": "The options to pass to the Realtime channel." + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + }, + "comment": { + "shortText": "Creates a Realtime channel with Broadcast, Presence, and Postgres Changes." + } + }, + "@supabase/supabase-js.SupabaseClient.from": { + "name": "@supabase/supabase-js.SupabaseClient.from", + "params": [ + { + "name": "relation", + "type": { + "type": "nameOnly", + "name": "TableName" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestQueryBuilder" + } + }, + "comment": { + "shortText": "Perform a query on a table or a view." + }, + "altSignatures": [ + { + "params": [ + { + "name": "relation", + "type": { + "type": "nameOnly", + "name": "ViewName" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestQueryBuilder" + } + } + } + ] + }, + "@supabase/supabase-js.SupabaseClient.getChannels": { + "name": "@supabase/supabase-js.SupabaseClient.getChannels", + "params": [], + "ret": { + "type": { + "type": "array", + "elemType": { + "type": "nameOnly", + "name": "RealtimeChannel" + } + } + }, + "comment": { + "shortText": "Returns all Realtime channels.", + "examples": [ + { + "id": "get-all-channels", + "name": "Get all channels", + "code": "```js\nconst channels = supabase.getChannels()\n```" + } + ] + } + }, + "@supabase/supabase-js.SupabaseClient.removeAllChannels": { + "name": "@supabase/supabase-js.SupabaseClient.removeAllChannels", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "array", + "elemType": { + "type": "union", + "name": "RealtimeRemoveChannelResponse", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + } + } + }, + "comment": { + "shortText": "Unsubscribes and removes all Realtime channels from Realtime client.", + "text": "- Removing channels is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed.", + "examples": [ + { + "id": "remove-all-channels", + "name": "Remove all channels", + "code": "```js\nsupabase.removeAllChannels()\n```" + } + ] + } + }, + "@supabase/supabase-js.SupabaseClient.removeChannel": { + "name": "@supabase/supabase-js.SupabaseClient.removeChannel", + "params": [ + { + "name": "channel", + "type": { + "type": "nameOnly", + "name": "RealtimeChannel" + }, + "comment": { + "shortText": "The name of the Realtime channel." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "RealtimeRemoveChannelResponse", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]", + null + ] + } + } + }, + "comment": { + "shortText": "Unsubscribes and removes Realtime channel from Realtime client.", + "text": "- Removing a channel is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed.", + "examples": [ + { + "id": "removes-a-channel", + "name": "Removes a channel", + "code": "```js\nsupabase.removeChannel(myChannel)\n```" + } + ] + } + }, + "@supabase/supabase-js.SupabaseClient.rpc": { + "name": "@supabase/supabase-js.SupabaseClient.rpc", + "params": [ + { + "name": "fn", + "type": { + "type": "nameOnly", + "name": "FnName" + }, + "comment": { + "shortText": "The function name to call" + } + }, + { + "name": "args", + "type": { + "type": "nameOnly", + "name": "Args" + }, + "comment": { + "shortText": "The arguments to pass to the function call" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "count", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": "exact" + }, + { + "type": "literal", + "value": "planned" + }, + { + "type": "literal", + "value": "estimated" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Count algorithm to use to count rows returned by the\nfunction. Only applicable for [set-returning\nfunctions](https://www.postgresql.org/docs/current/functions-srf.html).\n\n`\"exact\"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the\nhood.\n\n`\"planned\"`: Approximated but fast count algorithm. Uses the Postgres\nstatistics under the hood.\n\n`\"estimated\"`: Uses exact count for low numbers and planned count for high\nnumbers." + } + }, + { + "name": "get", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "When set to `true`, the function will be called with\nread-only access mode." + } + }, + { + "name": "head", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "When set to `true`, `data` will not be returned.\nUseful if you only need the count." + } + } + ] + }, + "comment": { + "shortText": "Named parameters" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, + "comment": { + "shortText": "Perform a function call." + } + }, + "@supabase/supabase-js.SupabaseClient.schema": { + "name": "@supabase/supabase-js.SupabaseClient.schema", + "params": [ + { + "name": "schema", + "type": { + "type": "nameOnly", + "name": "DynamicSchema" + }, + "comment": { + "shortText": "The schema to query" + } + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestClient" + } + }, + "comment": { + "shortText": "Select a schema to query or perform an function (rpc) call.\n\nThe schema needs to be on the list of exposed schemas inside Supabase." + } + }, + "@supabase/supabase-js.WebSocketFactory.getWebSocketConstructor": { + "name": "@supabase/supabase-js.WebSocketFactory.getWebSocketConstructor", + "params": [], + "ret": { + "type": { + "type": "function", + "params": [ + { + "name": "url", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "protocols", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "WebSocket" + } + } + } + }, + "comment": { + "shortText": "Returns the best available WebSocket constructor for the current runtime.", + "examples": [ + { + "id": "example-with-error-handling", + "name": "Example with error handling", + "code": "```ts\ntry {\n const WS = WebSocketFactory.getWebSocketConstructor()\n const socket = new WS('wss://example.com/socket')\n} catch (error) {\n console.error('WebSocket not available in this environment.', error)\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.WebSocketFactory.isWebSocketSupported": { + "name": "@supabase/supabase-js.WebSocketFactory.isWebSocketSupported", + "params": [], + "ret": { + "type": { + "type": "intrinsic", + "name": "boolean" + } + }, + "comment": { + "shortText": "Detects whether the runtime can establish WebSocket connections.", + "examples": [ + { + "id": "example-in-a-node-js-script", + "name": "Example in a Node.js script", + "code": "```ts\nif (!WebSocketFactory.isWebSocketSupported()) {\n console.error('WebSockets are required for this script.')\n process.exitCode = 1\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.AuthOAuthServerApi.approveAuthorization": { + "name": "@supabase/supabase-js.AuthOAuthServerApi.approveAuthorization", + "params": [ + { + "name": "authorizationId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The authorization ID to approve" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "skipBrowserRedirect", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If false (default), automatically redirects the browser to the OAuth client. If true, returns the redirect_url without automatic redirect (useful for custom handling)." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Optional parameters" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthOAuthConsentResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "OAuthRedirect", + "type": "object", + "properties": [ + { + "name": "redirect_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Complete redirect URL with authorization code and state parameters (e.g., \"https://app.com/callback?code=xxx&state=yyy\")" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Approves an OAuth authorization request.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nAfter approval, the user's consent is stored and an authorization code is generated.\nThe response contains a complete redirect URL with the authorization code and state." + } + }, + "@supabase/supabase-js.AuthOAuthServerApi.denyAuthorization": { + "name": "@supabase/supabase-js.AuthOAuthServerApi.denyAuthorization", + "params": [ + { + "name": "authorizationId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The authorization ID to deny" + } + }, + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "skipBrowserRedirect", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "If false (default), automatically redirects the browser to the OAuth client. If true, returns the redirect_url without automatic redirect (useful for custom handling)." + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Optional parameters" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthOAuthConsentResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "OAuthRedirect", + "type": "object", + "properties": [ + { + "name": "redirect_url", + "type": "[Circular]", + "comment": { + "shortText": "Complete redirect URL with authorization code and state parameters (e.g., \"https://app.com/callback?code=xxx&state=yyy\")" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Denies an OAuth authorization request.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nAfter denial, the response contains a redirect URL with an OAuth error\n(access_denied) to inform the OAuth client that the user rejected the request." + } + }, + "@supabase/supabase-js.AuthOAuthServerApi.getAuthorizationDetails": { + "name": "@supabase/supabase-js.AuthOAuthServerApi.getAuthorizationDetails", + "params": [ + { + "name": "authorizationId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The authorization ID from the authorization request" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthOAuthAuthorizationDetailsResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "union", + "subTypes": [ + { + "name": "OAuthAuthorizationDetails", + "type": "object", + "properties": [ + { + "name": "authorization_id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The authorization ID used to approve or deny the request" + } + }, + { + "name": "client", + "type": { + "name": "OAuthAuthorizationClient", + "type": "object", + "properties": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Unique identifier for the OAuth client (UUID)" + } + }, + { + "name": "logo_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "URI of the OAuth client's logo" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Human-readable name of the OAuth client" + } + }, + { + "name": "uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "URI of the OAuth client's website" + } + } + ] + }, + "comment": { + "shortText": "OAuth client requesting authorization" + } + }, + { + "name": "redirect_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The OAuth client's registered redirect URI (base URI without query parameters)" + } + }, + { + "name": "scope", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Space-separated list of requested scopes (e.g., \"openid profile email\")" + } + }, + { + "name": "user", + "type": { + "type": "object", + "properties": [ + { + "name": "email", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "User email" + } + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "User ID (UUID)" + } + } + ] + }, + "comment": { + "shortText": "User object associated with the authorization" + } + } + ] + }, + { + "name": "OAuthRedirect", + "type": "object", + "properties": [ + { + "name": "redirect_url", + "type": "[Circular]", + "comment": { + "shortText": "Complete redirect URL with authorization code and state parameters (e.g., \"https://app.com/callback?code=xxx&state=yyy\")" + } + } + ] + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Retrieves details about an OAuth authorization request.\nUsed to display consent information to the user.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nThis method returns one of two response types:\n- `OAuthAuthorizationDetails`: User needs to consent - show consent page with client info\n- `OAuthRedirect`: User already consented - redirect immediately to the OAuth client\n\nUse type narrowing to distinguish between the responses:\n```typescript\nif ('authorization_id' in data) {\n // Show consent page\n} else {\n // Redirect to data.redirect_url\n}\n```" + } + }, + "@supabase/supabase-js.AuthOAuthServerApi.listGrants": { + "name": "@supabase/supabase-js.AuthOAuthServerApi.listGrants", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthOAuthGrantsResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "array", + "elemType": { + "name": "OAuthGrant", + "type": "object", + "properties": [ + { + "name": "client", + "type": { + "name": "OAuthAuthorizationClient", + "type": "object", + "properties": [ + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier for the OAuth client (UUID)" + } + }, + { + "name": "logo_uri", + "type": "[Circular]", + "comment": { + "shortText": "URI of the OAuth client's logo" + } + }, + { + "name": "name", + "type": "[Circular]", + "comment": { + "shortText": "Human-readable name of the OAuth client" + } + }, + { + "name": "uri", + "type": "[Circular]", + "comment": { + "shortText": "URI of the OAuth client's website" + } + } + ] + }, + "comment": { + "shortText": "OAuth client information" + } + }, + { + "name": "granted_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Timestamp when the grant was created (ISO 8601 date-time)" + } + }, + { + "name": "scopes", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "comment": { + "shortText": "Array of scopes granted to this client" + } + } + ] + } + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists all OAuth grants that the authenticated user has authorized.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth." + } + }, + "@supabase/supabase-js.AuthOAuthServerApi.revokeGrant": { + "name": "@supabase/supabase-js.AuthOAuthServerApi.revokeGrant", + "params": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "clientId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The OAuth client identifier (UUID) to revoke access for" + } + } + ] + }, + "comment": { + "shortText": "Revocation options" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthOAuthRevokeGrantResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Revokes a user's OAuth grant for a specific client.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nRevocation marks consent as revoked, deletes active sessions for that OAuth client,\nand invalidates associated refresh tokens." + } + }, + "@supabase/supabase-js.AuthPasskeyApi.delete": { + "name": "@supabase/supabase-js.AuthPasskeyApi.delete", + "params": [ + { + "name": "params", + "type": { + "name": "PasskeyDeleteParams", + "type": "object", + "properties": [ + { + "name": "passkeyId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "UUID of the passkey to delete" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyDeleteResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Deletes a passkey for the currently signed-in user." + } + }, + "@supabase/supabase-js.AuthPasskeyApi.list": { + "name": "@supabase/supabase-js.AuthPasskeyApi.list", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyListResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "array", + "elemType": { + "name": "PasskeyListItem", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "friendly_name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "last_used_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + } + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists all passkeys registered for the currently signed-in user." + } + }, + "@supabase/supabase-js.AuthPasskeyApi.startAuthentication": { + "name": "@supabase/supabase-js.AuthPasskeyApi.startAuthentication", + "params": [ + { + "name": "params", + "type": { + "name": "StartPasskeyAuthenticationParams", + "type": "object", + "properties": [ + { + "name": "options", + "type": { + "type": "object", + "properties": [ + { + "name": "captchaToken", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyAuthenticationOptionsResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "PasskeyAuthenticationOptionsResponse", + "type": "object", + "properties": [ + { + "name": "challenge_id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "expires_at", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "options", + "type": { + "type": "nameOnly", + "name": "ServerCredentialRequestOptions" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Starts the passkey authentication ceremony. Fetches an authentication\nchallenge and credential request options from the server. Used as the\nfirst step of a two-step sign-in flow when the caller wants to handle\n`navigator.credentials.get()` themselves." + } + }, + "@supabase/supabase-js.AuthPasskeyApi.startRegistration": { + "name": "@supabase/supabase-js.AuthPasskeyApi.startRegistration", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyRegistrationOptionsResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "PasskeyRegistrationOptionsResponse", + "type": "object", + "properties": [ + { + "name": "challenge_id", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "expires_at", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "options", + "type": { + "type": "nameOnly", + "name": "ServerCredentialCreationOptions" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Starts the passkey registration ceremony. Fetches a registration challenge\nand credential creation options from the server. Used as the first step of\na two-step registration flow when the caller wants to handle\n`navigator.credentials.create()` themselves." + } + }, + "@supabase/supabase-js.AuthPasskeyApi.update": { + "name": "@supabase/supabase-js.AuthPasskeyApi.update", + "params": [ + { + "name": "params", + "type": { + "name": "PasskeyUpdateParams", + "type": "object", + "properties": [ + { + "name": "friendlyName", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "New friendly name (max 120 chars)" + } + }, + { + "name": "passkeyId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "UUID of the passkey to update" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyUpdateResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "PasskeyListItem", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "last_used_at", + "type": "[Circular]", + "isOptional": true + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Updates a passkey's friendly name." + } + }, + "@supabase/supabase-js.AuthPasskeyApi.verifyAuthentication": { + "name": "@supabase/supabase-js.AuthPasskeyApi.verifyAuthentication", + "params": [ + { + "name": "params", + "type": { + "name": "VerifyPasskeyAuthenticationParams", + "type": "object", + "properties": [ + { + "name": "challengeId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Challenge ID from startAuthentication" + } + }, + { + "name": "credential", + "type": { + "type": "nameOnly", + "name": "ServerCredentialResponse" + }, + "comment": { + "shortText": "Serialized credential from navigator.credentials.get()" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyAuthenticationVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "session", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthSession", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "The access token jwt. It is recommended to set the JWT_EXPIRY to a shorter expiry value." + } + }, + { + "name": "expires_at", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "A timestamp of when the token will expire. Returned when a login is confirmed." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "The number of seconds until the token expires (since it was issued). Returned when a login is confirmed." + } + }, + { + "name": "provider_refresh_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider refresh token. If present, this can be used to refresh the provider_token via the oauth provider's API.\nNot all oauth providers return a provider refresh token. If the provider_refresh_token is missing, please refer to the oauth provider's documentation for information on how to obtain the provider refresh token." + } + }, + { + "name": "provider_token", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "The oauth provider token. If present, this can be used to make external API requests to the oauth provider used." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "A one-time used refresh token that never expires." + } + }, + { + "name": "token_type", + "type": "[Circular]" + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "When using a separate user storage, accessing properties of this object will throw an error." + } + } + ] + }, + "[Circular]" + ] + } + }, + { + "name": "user", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "[Circular]" + ] + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Verifies a passkey authentication credential against a previously issued\nchallenge. Used as the second step of a two-step sign-in flow." + } + }, + "@supabase/supabase-js.AuthPasskeyApi.verifyRegistration": { + "name": "@supabase/supabase-js.AuthPasskeyApi.verifyRegistration", + "params": [ + { + "name": "params", + "type": { + "name": "VerifyPasskeyRegistrationParams", + "type": "object", + "properties": [ + { + "name": "challengeId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Challenge ID from startRegistration" + } + }, + { + "name": "credential", + "type": { + "type": "nameOnly", + "name": "ServerCredentialResponse" + }, + "comment": { + "shortText": "Serialized credential from navigator.credentials.create()" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyRegistrationVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "PasskeyMetadata", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Verifies a passkey registration credential against a previously issued\nchallenge. Used as the second step of a two-step registration flow." + } + }, + "@supabase/supabase-js.GoTrueAdminCustomProvidersApi.createProvider": { + "name": "@supabase/supabase-js.GoTrueAdminCustomProvidersApi.createProvider", + "params": [ + { + "name": "params", + "type": { + "name": "CreateCustomProviderParams", + "type": "object", + "properties": [ + { + "name": "acceptable_client_ids", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Additional client IDs accepted during token validation" + } + }, + { + "name": "attribute_mapping", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + "isOptional": true, + "comment": { + "shortText": "Mapping of provider attributes to Supabase user attributes" + } + }, + { + "name": "authorization_params", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Additional parameters sent with the authorization request" + } + }, + { + "name": "authorization_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 authorization URL" + } + }, + { + "name": "client_id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "OAuth client ID" + } + }, + { + "name": "client_secret", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "OAuth client secret (write-only, not returned in responses)" + } + }, + { + "name": "discovery_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OIDC discovery URL" + } + }, + { + "name": "email_optional", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether email is optional for this provider" + } + }, + { + "name": "enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether the provider is enabled" + } + }, + { + "name": "identifier", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Provider identifier (e.g. `custom:mycompany`)" + } + }, + { + "name": "issuer", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OIDC issuer URL" + } + }, + { + "name": "jwks_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "JWKS URI for token verification" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Human-readable name" + } + }, + { + "name": "pkce_enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether PKCE is enabled" + } + }, + { + "name": "provider_type", + "type": { + "type": "union", + "name": "CustomProviderType", + "subTypes": [ + { + "type": "literal", + "value": "oauth2" + }, + { + "type": "literal", + "value": "oidc" + } + ] + }, + "comment": { + "shortText": "Provider type" + } + }, + { + "name": "scopes", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "OAuth scopes requested during authorization" + } + }, + { + "name": "skip_nonce_check", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether to skip nonce check (OIDC)" + } + }, + { + "name": "token_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 token URL" + } + }, + { + "name": "userinfo_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 userinfo URL" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "CustomProviderResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "CustomOAuthProvider", + "type": "object", + "properties": [ + { + "name": "acceptable_client_ids", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Additional client IDs accepted during token validation" + } + }, + { + "name": "attribute_mapping", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + "isOptional": true, + "comment": { + "shortText": "Mapping of provider attributes to Supabase user attributes" + } + }, + { + "name": "authorization_params", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Additional parameters sent with the authorization request" + } + }, + { + "name": "authorization_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 authorization URL" + } + }, + { + "name": "client_id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "OAuth client ID" + } + }, + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Timestamp when the provider was created" + } + }, + { + "name": "discovery_document", + "type": { + "type": "union", + "subTypes": [ + { + "name": "OIDCDiscoveryDocument", + "type": "object", + "properties": [ + { + "name": "authorization_endpoint", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "URL of the authorization endpoint" + } + }, + { + "name": "issuer", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "The issuer identifier" + } + }, + { + "name": "jwks_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "URL of the JSON Web Key Set" + } + }, + { + "name": "revocation_endpoint", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URL of the revocation endpoint" + } + }, + { + "name": "supported_id_token_signing_algs", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "List of supported ID token signing algorithms" + } + }, + { + "name": "supported_response_types", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "List of supported response types" + } + }, + { + "name": "supported_scopes", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "List of supported scopes" + } + }, + { + "name": "supported_subject_types", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "List of supported subject types" + } + }, + { + "name": "token_endpoint", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "URL of the token endpoint" + } + }, + { + "name": "userinfo_endpoint", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URL of the userinfo endpoint" + } + } + ] + }, + { + "type": "literal", + "value": null + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "OIDC discovery document (OIDC providers only)" + } + }, + { + "name": "discovery_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OIDC discovery URL" + } + }, + { + "name": "email_optional", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether email is optional for this provider" + } + }, + { + "name": "enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether the provider is enabled" + } + }, + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Unique identifier (UUID)" + } + }, + { + "name": "identifier", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Provider identifier (e.g. `custom:mycompany`)" + } + }, + { + "name": "issuer", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OIDC issuer URL" + } + }, + { + "name": "jwks_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "JWKS URI for token verification" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Human-readable name" + } + }, + { + "name": "pkce_enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether PKCE is enabled" + } + }, + { + "name": "provider_type", + "type": { + "type": "union", + "name": "CustomProviderType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Provider type" + } + }, + { + "name": "scopes", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "OAuth scopes requested during authorization" + } + }, + { + "name": "skip_nonce_check", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether to skip nonce check (OIDC)" + } + }, + { + "name": "token_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 token URL" + } + }, + { + "name": "updated_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Timestamp when the provider was last updated" + } + }, + { + "name": "userinfo_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 userinfo URL" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a new custom OIDC/OAuth provider.\n\nFor OIDC providers, the server fetches and validates the OpenID Connect discovery document\nfrom the issuer's well-known endpoint (or the provided `discovery_url`) at creation time.\nThis may return a validation error (`error_code: \"validation_failed\"`) if the discovery\ndocument is unreachable, not valid JSON, missing required fields, or if the issuer\nin the document does not match the expected issuer.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/supabase-js.GoTrueAdminCustomProvidersApi.deleteProvider": { + "name": "@supabase/supabase-js.GoTrueAdminCustomProvidersApi.deleteProvider", + "params": [ + { + "name": "identifier", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "nameOnly", + "name": "AuthError" + } + ] + } + } + ] + } + } + }, + "comment": { + "shortText": "Deletes a custom provider.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/supabase-js.GoTrueAdminCustomProvidersApi.getProvider": { + "name": "@supabase/supabase-js.GoTrueAdminCustomProvidersApi.getProvider", + "params": [ + { + "name": "identifier", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "CustomProviderResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "CustomOAuthProvider", + "type": "object", + "properties": [ + { + "name": "acceptable_client_ids", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Additional client IDs accepted during token validation" + } + }, + { + "name": "attribute_mapping", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Mapping of provider attributes to Supabase user attributes" + } + }, + { + "name": "authorization_params", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Additional parameters sent with the authorization request" + } + }, + { + "name": "authorization_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 authorization URL" + } + }, + { + "name": "client_id", + "type": "[Circular]", + "comment": { + "shortText": "OAuth client ID" + } + }, + { + "name": "created_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the provider was created" + } + }, + { + "name": "discovery_document", + "type": { + "type": "union", + "subTypes": [ + { + "name": "OIDCDiscoveryDocument", + "type": "object", + "properties": [ + { + "name": "authorization_endpoint", + "type": "[Circular]", + "comment": { + "shortText": "URL of the authorization endpoint" + } + }, + { + "name": "issuer", + "type": "[Circular]", + "comment": { + "shortText": "The issuer identifier" + } + }, + { + "name": "jwks_uri", + "type": "[Circular]", + "comment": { + "shortText": "URL of the JSON Web Key Set" + } + }, + { + "name": "revocation_endpoint", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URL of the revocation endpoint" + } + }, + { + "name": "supported_id_token_signing_algs", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported ID token signing algorithms" + } + }, + { + "name": "supported_response_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported response types" + } + }, + { + "name": "supported_scopes", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported scopes" + } + }, + { + "name": "supported_subject_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported subject types" + } + }, + { + "name": "token_endpoint", + "type": "[Circular]", + "comment": { + "shortText": "URL of the token endpoint" + } + }, + { + "name": "userinfo_endpoint", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URL of the userinfo endpoint" + } + } + ] + }, + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "OIDC discovery document (OIDC providers only)" + } + }, + { + "name": "discovery_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OIDC discovery URL" + } + }, + { + "name": "email_optional", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether email is optional for this provider" + } + }, + { + "name": "enabled", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether the provider is enabled" + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier (UUID)" + } + }, + { + "name": "identifier", + "type": "[Circular]", + "comment": { + "shortText": "Provider identifier (e.g. `custom:mycompany`)" + } + }, + { + "name": "issuer", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OIDC issuer URL" + } + }, + { + "name": "jwks_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "JWKS URI for token verification" + } + }, + { + "name": "name", + "type": "[Circular]", + "comment": { + "shortText": "Human-readable name" + } + }, + { + "name": "pkce_enabled", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether PKCE is enabled" + } + }, + { + "name": "provider_type", + "type": { + "type": "union", + "name": "CustomProviderType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Provider type" + } + }, + { + "name": "scopes", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth scopes requested during authorization" + } + }, + { + "name": "skip_nonce_check", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether to skip nonce check (OIDC)" + } + }, + { + "name": "token_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 token URL" + } + }, + { + "name": "updated_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the provider was last updated" + } + }, + { + "name": "userinfo_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 userinfo URL" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Gets details of a specific custom provider by identifier.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/supabase-js.GoTrueAdminCustomProvidersApi.listProviders": { + "name": "@supabase/supabase-js.GoTrueAdminCustomProvidersApi.listProviders", + "params": [ + { + "name": "params", + "type": { + "name": "ListCustomProvidersParams", + "type": "object", + "properties": [ + { + "name": "type", + "type": { + "type": "union", + "name": "CustomProviderType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "Filter by provider type" + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "CustomProviderListResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "providers", + "type": { + "type": "array", + "elemType": { + "name": "CustomOAuthProvider", + "type": "object", + "properties": [ + { + "name": "acceptable_client_ids", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Additional client IDs accepted during token validation" + } + }, + { + "name": "attribute_mapping", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Mapping of provider attributes to Supabase user attributes" + } + }, + { + "name": "authorization_params", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Additional parameters sent with the authorization request" + } + }, + { + "name": "authorization_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 authorization URL" + } + }, + { + "name": "client_id", + "type": "[Circular]", + "comment": { + "shortText": "OAuth client ID" + } + }, + { + "name": "created_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the provider was created" + } + }, + { + "name": "discovery_document", + "type": { + "type": "union", + "subTypes": [ + { + "name": "OIDCDiscoveryDocument", + "type": "object", + "properties": [ + { + "name": "authorization_endpoint", + "type": "[Circular]", + "comment": { + "shortText": "URL of the authorization endpoint" + } + }, + { + "name": "issuer", + "type": "[Circular]", + "comment": { + "shortText": "The issuer identifier" + } + }, + { + "name": "jwks_uri", + "type": "[Circular]", + "comment": { + "shortText": "URL of the JSON Web Key Set" + } + }, + { + "name": "revocation_endpoint", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URL of the revocation endpoint" + } + }, + { + "name": "supported_id_token_signing_algs", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported ID token signing algorithms" + } + }, + { + "name": "supported_response_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported response types" + } + }, + { + "name": "supported_scopes", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported scopes" + } + }, + { + "name": "supported_subject_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported subject types" + } + }, + { + "name": "token_endpoint", + "type": "[Circular]", + "comment": { + "shortText": "URL of the token endpoint" + } + }, + { + "name": "userinfo_endpoint", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URL of the userinfo endpoint" + } + } + ] + }, + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "OIDC discovery document (OIDC providers only)" + } + }, + { + "name": "discovery_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OIDC discovery URL" + } + }, + { + "name": "email_optional", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether email is optional for this provider" + } + }, + { + "name": "enabled", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether the provider is enabled" + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier (UUID)" + } + }, + { + "name": "identifier", + "type": "[Circular]", + "comment": { + "shortText": "Provider identifier (e.g. `custom:mycompany`)" + } + }, + { + "name": "issuer", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OIDC issuer URL" + } + }, + { + "name": "jwks_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "JWKS URI for token verification" + } + }, + { + "name": "name", + "type": "[Circular]", + "comment": { + "shortText": "Human-readable name" + } + }, + { + "name": "pkce_enabled", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether PKCE is enabled" + } + }, + { + "name": "provider_type", + "type": { + "type": "union", + "name": "CustomProviderType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Provider type" + } + }, + { + "name": "scopes", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth scopes requested during authorization" + } + }, + { + "name": "skip_nonce_check", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether to skip nonce check (OIDC)" + } + }, + { + "name": "token_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 token URL" + } + }, + { + "name": "updated_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the provider was last updated" + } + }, + { + "name": "userinfo_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 userinfo URL" + } + } + ] + } + } + } + ] + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "providers" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists all custom providers with optional type filter.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/supabase-js.GoTrueAdminCustomProvidersApi.updateProvider": { + "name": "@supabase/supabase-js.GoTrueAdminCustomProvidersApi.updateProvider", + "params": [ + { + "name": "identifier", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "params", + "type": { + "name": "UpdateCustomProviderParams", + "type": "object", + "properties": [ + { + "name": "acceptable_client_ids", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Additional client IDs accepted during token validation" + } + }, + { + "name": "attribute_mapping", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "any" + } + }, + "isOptional": true, + "comment": { + "shortText": "Mapping of provider attributes to Supabase user attributes" + } + }, + { + "name": "authorization_params", + "type": { + "type": "record", + "name": "Record", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Additional parameters sent with the authorization request" + } + }, + { + "name": "authorization_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 authorization URL" + } + }, + { + "name": "client_id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth client ID" + } + }, + { + "name": "client_secret", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth client secret (write-only, not returned in responses)" + } + }, + { + "name": "discovery_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OIDC discovery URL" + } + }, + { + "name": "email_optional", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether email is optional for this provider" + } + }, + { + "name": "enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether the provider is enabled" + } + }, + { + "name": "issuer", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OIDC issuer URL" + } + }, + { + "name": "jwks_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "JWKS URI for token verification" + } + }, + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Human-readable name" + } + }, + { + "name": "pkce_enabled", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether PKCE is enabled" + } + }, + { + "name": "scopes", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "OAuth scopes requested during authorization" + } + }, + { + "name": "skip_nonce_check", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "isOptional": true, + "comment": { + "shortText": "Whether to skip nonce check (OIDC)" + } + }, + { + "name": "token_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 token URL" + } + }, + { + "name": "userinfo_url", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth2 userinfo URL" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "CustomProviderResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "CustomOAuthProvider", + "type": "object", + "properties": [ + { + "name": "acceptable_client_ids", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Additional client IDs accepted during token validation" + } + }, + { + "name": "attribute_mapping", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Mapping of provider attributes to Supabase user attributes" + } + }, + { + "name": "authorization_params", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Additional parameters sent with the authorization request" + } + }, + { + "name": "authorization_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 authorization URL" + } + }, + { + "name": "client_id", + "type": "[Circular]", + "comment": { + "shortText": "OAuth client ID" + } + }, + { + "name": "created_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the provider was created" + } + }, + { + "name": "discovery_document", + "type": { + "type": "union", + "subTypes": [ + { + "name": "OIDCDiscoveryDocument", + "type": "object", + "properties": [ + { + "name": "authorization_endpoint", + "type": "[Circular]", + "comment": { + "shortText": "URL of the authorization endpoint" + } + }, + { + "name": "issuer", + "type": "[Circular]", + "comment": { + "shortText": "The issuer identifier" + } + }, + { + "name": "jwks_uri", + "type": "[Circular]", + "comment": { + "shortText": "URL of the JSON Web Key Set" + } + }, + { + "name": "revocation_endpoint", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URL of the revocation endpoint" + } + }, + { + "name": "supported_id_token_signing_algs", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported ID token signing algorithms" + } + }, + { + "name": "supported_response_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported response types" + } + }, + { + "name": "supported_scopes", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported scopes" + } + }, + { + "name": "supported_subject_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "List of supported subject types" + } + }, + { + "name": "token_endpoint", + "type": "[Circular]", + "comment": { + "shortText": "URL of the token endpoint" + } + }, + { + "name": "userinfo_endpoint", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URL of the userinfo endpoint" + } + } + ] + }, + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "OIDC discovery document (OIDC providers only)" + } + }, + { + "name": "discovery_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OIDC discovery URL" + } + }, + { + "name": "email_optional", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether email is optional for this provider" + } + }, + { + "name": "enabled", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether the provider is enabled" + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier (UUID)" + } + }, + { + "name": "identifier", + "type": "[Circular]", + "comment": { + "shortText": "Provider identifier (e.g. `custom:mycompany`)" + } + }, + { + "name": "issuer", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OIDC issuer URL" + } + }, + { + "name": "jwks_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "JWKS URI for token verification" + } + }, + { + "name": "name", + "type": "[Circular]", + "comment": { + "shortText": "Human-readable name" + } + }, + { + "name": "pkce_enabled", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether PKCE is enabled" + } + }, + { + "name": "provider_type", + "type": { + "type": "union", + "name": "CustomProviderType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Provider type" + } + }, + { + "name": "scopes", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth scopes requested during authorization" + } + }, + { + "name": "skip_nonce_check", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether to skip nonce check (OIDC)" + } + }, + { + "name": "token_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 token URL" + } + }, + { + "name": "updated_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the provider was last updated" + } + }, + { + "name": "userinfo_url", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "OAuth2 userinfo URL" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Updates an existing custom provider.\n\nWhen `issuer` or `discovery_url` is changed on an OIDC provider, the server re-fetches and\nvalidates the discovery document before persisting. This may return a validation error\n(`error_code: \"validation_failed\"`) if the discovery document is unreachable, invalid, or\nthe issuer does not match.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/supabase-js.GoTrueAdminMFAApi.deleteFactor": { + "name": "@supabase/supabase-js.GoTrueAdminMFAApi.deleteFactor", + "params": [ + { + "name": "params", + "type": { + "name": "AuthMFAAdminDeleteFactorParams", + "type": "object", + "properties": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "ID of the MFA factor to delete." + } + }, + { + "name": "userId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "ID of the user whose factor is being deleted." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAAdminDeleteFactorResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "ID of the factor that was successfully deleted." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Deletes a factor on a user. This will log the user out of all active\nsessions if the deleted factor was verified.", + "examples": [ + { + "id": "delete-a-factor-for-a-user", + "name": "Delete a factor for a user", + "code": "```js\nconst { data, error } = await supabase.auth.admin.mfa.deleteFactor({\n id: '34e770dd-9ff9-416c-87fa-43b31d7ef225',\n userId: 'a89baba7-b1b7-440f-b4bb-91026967f66b',\n})\n```", + "response": "```json\n{\n data: {\n id: '34e770dd-9ff9-416c-87fa-43b31d7ef225'\n },\n error: null\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueAdminMFAApi.listFactors": { + "name": "@supabase/supabase-js.GoTrueAdminMFAApi.listFactors", + "params": [ + { + "name": "params", + "type": { + "name": "AuthMFAAdminListFactorsParams", + "type": "object", + "properties": [ + { + "name": "userId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "ID of the user." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAAdminListFactorsResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "nameOnly", + "name": "Type" + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "nameOnly", + "name": "Status" + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + }, + "comment": { + "shortText": "All factors attached to the user." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists all factors associated to a user.", + "examples": [ + { + "id": "list-all-factors-for-a-user", + "name": "List all factors for a user", + "code": "```js\nconst { data, error } = await supabase.auth.admin.mfa.listFactors()\n```", + "response": "```json\n{\n data: {\n factors: Factor[\n {\n id: '',\n friendly_name: 'Auth App Factor',\n factor_type: 'totp',\n status: 'verified',\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z'\n }\n ]\n },\n error: null\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueAdminOAuthApi.createClient": { + "name": "@supabase/supabase-js.GoTrueAdminOAuthApi.createClient", + "params": [ + { + "name": "params", + "type": { + "name": "CreateOAuthClientParams", + "type": "object", + "properties": [ + { + "name": "client_name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Human-readable name of the OAuth client" + } + }, + { + "name": "client_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client" + } + }, + { + "name": "grant_types", + "type": { + "type": "array", + "elemType": { + "type": "union", + "name": "OAuthClientGrantType", + "subTypes": [ + { + "type": "literal", + "value": "authorization_code" + }, + { + "type": "literal", + "value": "refresh_token" + }, + null + ] + } + }, + "isOptional": true, + "comment": { + "shortText": "Array of allowed grant types (optional, defaults to authorization_code and refresh_token)" + } + }, + { + "name": "redirect_uris", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "comment": { + "shortText": "Array of allowed redirect URIs" + } + }, + { + "name": "response_types", + "type": { + "type": "array", + "elemType": { + "type": "literal", + "value": "code", + "name": "OAuthClientResponseType" + } + }, + "isOptional": true, + "comment": { + "shortText": "Array of allowed response types (optional, defaults to code)" + } + }, + { + "name": "scope", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Scope of the OAuth client" + } + }, + { + "name": "token_endpoint_auth_method", + "type": { + "type": "union", + "name": "OAuthClientTokenEndpointAuthMethod", + "subTypes": [ + { + "type": "literal", + "value": "none" + }, + { + "type": "literal", + "value": "client_secret_basic" + }, + { + "type": "literal", + "value": "client_secret_post" + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Token endpoint authentication method (defaults to server default if not specified)" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "OAuthClientResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "OAuthClient", + "type": "object", + "properties": [ + { + "name": "client_id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Unique identifier for the OAuth client" + } + }, + { + "name": "client_name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Human-readable name of the OAuth client" + } + }, + { + "name": "client_secret", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Client secret (only returned on registration and regeneration)" + } + }, + { + "name": "client_type", + "type": { + "type": "union", + "name": "OAuthClientType", + "subTypes": [ + { + "type": "literal", + "value": "public" + }, + { + "type": "literal", + "value": "confidential" + } + ] + }, + "comment": { + "shortText": "Type of OAuth client" + } + }, + { + "name": "client_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client" + } + }, + { + "name": "created_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Timestamp when the client was created" + } + }, + { + "name": "grant_types", + "type": { + "type": "array", + "elemType": { + "type": "union", + "name": "OAuthClientGrantType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + } + }, + "comment": { + "shortText": "Array of allowed grant types" + } + }, + { + "name": "logo_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client's logo" + } + }, + { + "name": "redirect_uris", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "comment": { + "shortText": "Array of allowed redirect URIs" + } + }, + { + "name": "registration_type", + "type": { + "type": "union", + "name": "OAuthClientRegistrationType", + "subTypes": [ + { + "type": "literal", + "value": "dynamic" + }, + { + "type": "literal", + "value": "manual" + } + ] + }, + "comment": { + "shortText": "Registration type of the client" + } + }, + { + "name": "response_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "comment": { + "shortText": "Array of allowed response types" + } + }, + { + "name": "scope", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Scope of the OAuth client" + } + }, + { + "name": "token_endpoint_auth_method", + "type": { + "type": "union", + "name": "OAuthClientTokenEndpointAuthMethod", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Token endpoint authentication method" + } + }, + { + "name": "updated_at", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Timestamp when the client was last updated" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Creates a new OAuth client.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/supabase-js.GoTrueAdminOAuthApi.deleteClient": { + "name": "@supabase/supabase-js.GoTrueAdminOAuthApi.deleteClient", + "params": [ + { + "name": "clientId", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "nameOnly", + "name": "AuthError" + } + ] + } + } + ] + } + } + }, + "comment": { + "shortText": "Deletes an OAuth client.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/supabase-js.GoTrueAdminOAuthApi.getClient": { + "name": "@supabase/supabase-js.GoTrueAdminOAuthApi.getClient", + "params": [ + { + "name": "clientId", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "OAuthClientResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "OAuthClient", + "type": "object", + "properties": [ + { + "name": "client_id", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier for the OAuth client" + } + }, + { + "name": "client_name", + "type": "[Circular]", + "comment": { + "shortText": "Human-readable name of the OAuth client" + } + }, + { + "name": "client_secret", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Client secret (only returned on registration and regeneration)" + } + }, + { + "name": "client_type", + "type": { + "type": "union", + "name": "OAuthClientType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of OAuth client" + } + }, + { + "name": "client_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client" + } + }, + { + "name": "created_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the client was created" + } + }, + { + "name": "grant_types", + "type": { + "type": "array", + "elemType": { + "type": "union", + "name": "OAuthClientGrantType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + } + }, + "comment": { + "shortText": "Array of allowed grant types" + } + }, + { + "name": "logo_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client's logo" + } + }, + { + "name": "redirect_uris", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "comment": { + "shortText": "Array of allowed redirect URIs" + } + }, + { + "name": "registration_type", + "type": { + "type": "union", + "name": "OAuthClientRegistrationType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Registration type of the client" + } + }, + { + "name": "response_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "comment": { + "shortText": "Array of allowed response types" + } + }, + { + "name": "scope", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Scope of the OAuth client" + } + }, + { + "name": "token_endpoint_auth_method", + "type": { + "type": "union", + "name": "OAuthClientTokenEndpointAuthMethod", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Token endpoint authentication method" + } + }, + { + "name": "updated_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the client was last updated" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Gets details of a specific OAuth client.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/supabase-js.GoTrueAdminOAuthApi.listClients": { + "name": "@supabase/supabase-js.GoTrueAdminOAuthApi.listClients", + "params": [ + { + "name": "params", + "type": { + "name": "PageParams", + "type": "object", + "properties": [ + { + "name": "page", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The page number" + } + }, + { + "name": "perPage", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Number of items returned per page" + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "OAuthClientListResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "clients" + } + ] + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists all OAuth clients with optional pagination.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/supabase-js.GoTrueAdminOAuthApi.regenerateClientSecret": { + "name": "@supabase/supabase-js.GoTrueAdminOAuthApi.regenerateClientSecret", + "params": [ + { + "name": "clientId", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "OAuthClientResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "OAuthClient", + "type": "object", + "properties": [ + { + "name": "client_id", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier for the OAuth client" + } + }, + { + "name": "client_name", + "type": "[Circular]", + "comment": { + "shortText": "Human-readable name of the OAuth client" + } + }, + { + "name": "client_secret", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Client secret (only returned on registration and regeneration)" + } + }, + { + "name": "client_type", + "type": { + "type": "union", + "name": "OAuthClientType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of OAuth client" + } + }, + { + "name": "client_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client" + } + }, + { + "name": "created_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the client was created" + } + }, + { + "name": "grant_types", + "type": { + "type": "array", + "elemType": { + "type": "union", + "name": "OAuthClientGrantType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + } + }, + "comment": { + "shortText": "Array of allowed grant types" + } + }, + { + "name": "logo_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client's logo" + } + }, + { + "name": "redirect_uris", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "comment": { + "shortText": "Array of allowed redirect URIs" + } + }, + { + "name": "registration_type", + "type": { + "type": "union", + "name": "OAuthClientRegistrationType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Registration type of the client" + } + }, + { + "name": "response_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "comment": { + "shortText": "Array of allowed response types" + } + }, + { + "name": "scope", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Scope of the OAuth client" + } + }, + { + "name": "token_endpoint_auth_method", + "type": { + "type": "union", + "name": "OAuthClientTokenEndpointAuthMethod", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Token endpoint authentication method" + } + }, + { + "name": "updated_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the client was last updated" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Regenerates the secret for an OAuth client.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/supabase-js.GoTrueAdminOAuthApi.updateClient": { + "name": "@supabase/supabase-js.GoTrueAdminOAuthApi.updateClient", + "params": [ + { + "name": "clientId", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "params", + "type": { + "name": "UpdateOAuthClientParams", + "type": "object", + "properties": [ + { + "name": "client_name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Human-readable name of the OAuth client" + } + }, + { + "name": "client_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client" + } + }, + { + "name": "grant_types", + "type": { + "type": "array", + "elemType": { + "type": "union", + "name": "OAuthClientGrantType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + } + }, + "isOptional": true, + "comment": { + "shortText": "Array of allowed grant types" + } + }, + { + "name": "logo_uri", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client's logo" + } + }, + { + "name": "redirect_uris", + "type": { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + }, + "isOptional": true, + "comment": { + "shortText": "Array of allowed redirect URIs" + } + }, + { + "name": "token_endpoint_auth_method", + "type": { + "type": "union", + "name": "OAuthClientTokenEndpointAuthMethod", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "Token endpoint authentication method" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "OAuthClientResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "OAuthClient", + "type": "object", + "properties": [ + { + "name": "client_id", + "type": "[Circular]", + "comment": { + "shortText": "Unique identifier for the OAuth client" + } + }, + { + "name": "client_name", + "type": "[Circular]", + "comment": { + "shortText": "Human-readable name of the OAuth client" + } + }, + { + "name": "client_secret", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Client secret (only returned on registration and regeneration)" + } + }, + { + "name": "client_type", + "type": { + "type": "union", + "name": "OAuthClientType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of OAuth client" + } + }, + { + "name": "client_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client" + } + }, + { + "name": "created_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the client was created" + } + }, + { + "name": "grant_types", + "type": { + "type": "array", + "elemType": { + "type": "union", + "name": "OAuthClientGrantType", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + } + }, + "comment": { + "shortText": "Array of allowed grant types" + } + }, + { + "name": "logo_uri", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "URI of the OAuth client's logo" + } + }, + { + "name": "redirect_uris", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "comment": { + "shortText": "Array of allowed redirect URIs" + } + }, + { + "name": "registration_type", + "type": { + "type": "union", + "name": "OAuthClientRegistrationType", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Registration type of the client" + } + }, + { + "name": "response_types", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "comment": { + "shortText": "Array of allowed response types" + } + }, + { + "name": "scope", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Scope of the OAuth client" + } + }, + { + "name": "token_endpoint_auth_method", + "type": { + "type": "union", + "name": "OAuthClientTokenEndpointAuthMethod", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Token endpoint authentication method" + } + }, + { + "name": "updated_at", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the client was last updated" + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Updates an existing OAuth client.\nOnly relevant when the OAuth 2.1 server is enabled in Supabase Auth.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/supabase-js.GoTrueAdminPasskeyApi.deletePasskey": { + "name": "@supabase/supabase-js.GoTrueAdminPasskeyApi.deletePasskey", + "params": [ + { + "name": "params", + "type": { + "name": "AuthPasskeyAdminDeleteParams", + "type": "object", + "properties": [ + { + "name": "passkeyId", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "userId", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyDeleteResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Deletes a specific passkey for a specific user.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/supabase-js.GoTrueAdminPasskeyApi.listPasskeys": { + "name": "@supabase/supabase-js.GoTrueAdminPasskeyApi.listPasskeys", + "params": [ + { + "name": "params", + "type": { + "name": "AuthPasskeyAdminListParams", + "type": "object", + "properties": [ + { + "name": "userId", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthPasskeyListResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "array", + "elemType": { + "name": "PasskeyListItem", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "last_used_at", + "type": "[Circular]", + "isOptional": true + } + ] + } + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Lists all passkeys registered for a specific user.\n\nThis function should only be called on a server. Never expose your `service_role` key in the browser." + } + }, + "@supabase/supabase-js.GoTrueMFAApi.challenge": { + "name": "@supabase/supabase-js.GoTrueMFAApi.challenge", + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAChallengeParamsBase" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "nameOnly", + "name": "AuthMFAChallengeResponseBase" + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Prepares a challenge used to verify that a user has access to a MFA\nfactor.", + "text": "- An [enrolled factor](/docs/reference/javascript/auth-mfa-enroll) is required before creating a challenge.\n- To verify a challenge, see [`mfa.verify()`](/docs/reference/javascript/auth-mfa-verify).\n- A phone factor sends a code to the user upon challenge. The channel defaults to `sms` unless otherwise specified.", + "examples": [ + { + "id": "create-a-challenge-for-a-factor", + "name": "Create a challenge for a factor", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.challenge({\n factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225'\n})\n```", + "response": "```json\n{\n data: {\n id: '',\n type: 'totp',\n expires_at: 1700000000\n },\n error: null\n}\n```" + }, + { + "id": "create-a-challenge-for-a-phone-factor", + "name": "Create a challenge for a phone factor", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.challenge({\n factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',\n})\n```", + "response": "```json\n{\n data: {\n id: '',\n type: 'phone',\n expires_at: 1700000000\n },\n error: null\n}\n```" + }, + { + "id": "create-a-challenge-for-a-phone-factor-whatsapp", + "name": "Create a challenge for a phone factor (WhatsApp)", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.challenge({\n factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',\n channel: 'whatsapp',\n})\n```", + "response": "```json\n{\n data: {\n id: '',\n expires_at: 1700000000\n },\n error: null\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAChallengePhoneParams" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "nameOnly", + "name": "AuthMFAChallengeResponseBase" + } + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + } + ] + } + } + } + }, + { + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAChallengeWebauthnParams" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "literal", + "value": null + } + }, + { + "name": "error", + "type": { + "type": "nameOnly", + "name": "AuthError" + } + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": { + "type": "literal", + "value": null + } + } + ] + } + ] + } + } + } + }, + { + "params": [ + { + "name": "params", + "type": { + "type": "union", + "name": "MFAChallengeParams", + "subTypes": [ + { + "type": "nameOnly", + "name": "MFAChallengeTOTPParams" + }, + { + "type": "nameOnly", + "name": "MFAChallengePhoneParams" + }, + { + "type": "nameOnly", + "name": "MFAChallengeWebauthnParams" + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAChallengeResponse", + "subTypes": [ + { + "type": "union", + "name": "AuthMFAChallengeTOTPResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + }, + { + "type": "union", + "name": "AuthMFAChallengePhoneResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + }, + { + "type": "union", + "name": "AuthMFAChallengeWebauthnResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + ] + } + } + } + } + ] + }, + "@supabase/supabase-js.GoTrueMFAApi.challengeAndVerify": { + "name": "@supabase/supabase-js.GoTrueMFAApi.challengeAndVerify", + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAChallengeAndVerifyTOTPParams" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "AuthMFAVerifyResponseData", + "type": "object", + "properties": [ + { + "name": "access_token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "New access token (JWT) after successful verification." + } + }, + { + "name": "expires_in", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "Number of seconds in which the access token will expire." + } + }, + { + "name": "refresh_token", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Refresh token you can use to obtain new access tokens when expired." + } + }, + { + "name": "token_type", + "type": { + "type": "literal", + "value": "bearer" + }, + "comment": { + "shortText": "Type of token, always `bearer`." + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "Updated user profile." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Helper method which creates a challenge and immediately uses the given code to verify against it thereafter. The verification code is\nprovided by the user by entering a code seen in their authenticator app.", + "text": "- Intended for use with only TOTP factors.\n- An [enrolled factor](/docs/reference/javascript/auth-mfa-enroll) is required before invoking `challengeAndVerify()`.\n- Executes [`mfa.challenge()`](/docs/reference/javascript/auth-mfa-challenge) and [`mfa.verify()`](/docs/reference/javascript/auth-mfa-verify) in a single step.", + "examples": [ + { + "id": "create-and-verify-a-challenge-for-a-factor", + "name": "Create and verify a challenge for a factor", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.challengeAndVerify({\n factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',\n code: '123456'\n})\n```", + "response": "```json\n{\n data: {\n access_token: '',\n token_type: 'Bearer',\n expires_in: 3600,\n refresh_token: '',\n user: {\n id: '11111111-1111-1111-1111-111111111111',\n aud: 'authenticated',\n role: 'authenticated',\n email: 'example@email.com',\n email_confirmed_at: '2024-01-01T00:00:00Z',\n phone: '',\n confirmation_sent_at: '2024-01-01T00:00:00Z',\n confirmed_at: '2024-01-01T00:00:00Z',\n last_sign_in_at: '2024-01-01T00:00:00Z',\n app_metadata: {\n provider: 'email',\n providers: [\n \"email\",\n ]\n },\n user_metadata: {},\n identities: [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": true,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"email@example.com\"\n },\n ],\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n is_anonymous: false,\n factors: [\n \"id\": '',\n \"friendly_name\": 'Important Auth App',\n \"factor_type\": 'totp',\n \"status\": 'verified',\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\"\n ]\n }\n }\n error: null\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueMFAApi.enroll": { + "name": "@supabase/supabase-js.GoTrueMFAApi.enroll", + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAEnrollTOTPParams" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAEnrollTOTPResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Starts the enrollment process for a new Multi-Factor Authentication (MFA)\nfactor. This method creates a new `unverified` factor.\nTo verify a factor, present the QR code or secret to the user and ask them to add it to their\nauthenticator app.\nThe user has to enter the code from their authenticator app to verify it.\n\nUpon verifying a factor, all other sessions are logged out and the current session's authenticator level is promoted to `aal2`.", + "text": "- Use `totp` or `phone` as the `factorType` and use the returned `id` to create a challenge.\n- To create a challenge, see [`mfa.challenge()`](/docs/reference/javascript/auth-mfa-challenge).\n- To verify a challenge, see [`mfa.verify()`](/docs/reference/javascript/auth-mfa-verify).\n- To create and verify a TOTP challenge in a single step, see [`mfa.challengeAndVerify()`](/docs/reference/javascript/auth-mfa-challengeandverify).\n- To generate a QR code for the `totp` secret in Next.js, you can do the following:\n```html\n{data.totp.uri}\n```\n- The `challenge` and `verify` steps are separated when using Phone factors as the user will need time to receive and input the code obtained from the SMS in challenge.", + "examples": [ + { + "id": "enroll-a-time-based-one-time-password-totp-factor", + "name": "Enroll a time-based, one-time password (TOTP) factor", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.enroll({\n factorType: 'totp',\n friendlyName: 'your_friendly_name'\n})\n\n// Use the id to create a challenge.\n// The challenge can be verified by entering the code generated from the authenticator app.\n// The code will be generated upon scanning the qr_code or entering the secret into the authenticator app.\nconst { id, type, totp: { qr_code, secret, uri }, friendly_name } = data\nconst challenge = await supabase.auth.mfa.challenge({ factorId: id });\n```", + "response": "```json\n{\n data: {\n id: '',\n type: 'totp'\n totp: {\n qr_code: '',\n secret: '',\n uri: '',\n }\n friendly_name?: 'Important app'\n },\n error: null\n}\n```" + }, + { + "id": "enroll-a-phone-factor", + "name": "Enroll a Phone Factor", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.enroll({\n factorType: 'phone',\n friendlyName: 'your_friendly_name',\n phone: '+12345678',\n})\n\n// Use the id to create a challenge and send an SMS with a code to the user.\nconst { id, type, friendly_name, phone } = data\n\nconst challenge = await supabase.auth.mfa.challenge({ factorId: id });\n```", + "response": "```json\n{\n data: {\n id: '',\n type: 'phone',\n friendly_name?: 'Important app',\n phone: '+5787123456'\n },\n error: null\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAEnrollPhoneParams" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAEnrollPhoneResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + } + }, + { + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAEnrollParamsBase" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAEnrollWebauthnResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + } + }, + { + "params": [ + { + "name": "params", + "type": { + "type": "union", + "name": "MFAEnrollParams", + "subTypes": [ + { + "type": "nameOnly", + "name": "MFAEnrollTOTPParams" + }, + { + "type": "nameOnly", + "name": "MFAEnrollPhoneParams" + }, + { + "type": "nameOnly", + "name": "MFAEnrollWebauthnParams" + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAEnrollResponse", + "subTypes": [ + { + "type": "union", + "name": "AuthMFAEnrollTOTPResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + }, + { + "type": "union", + "name": "AuthMFAEnrollPhoneResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + }, + { + "type": "union", + "name": "AuthMFAEnrollWebauthnResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + ] + } + } + } + } + ] + }, + "@supabase/supabase-js.GoTrueMFAApi.getAuthenticatorAssuranceLevel": { + "name": "@supabase/supabase-js.GoTrueMFAApi.getAuthenticatorAssuranceLevel", + "params": [ + { + "name": "jwt", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true, + "comment": { + "shortText": "Takes in an optional access token JWT. If no JWT is provided, the JWT from the current session is used." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAGetAuthenticatorAssuranceLevelResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "currentAuthenticationMethods", + "type": { + "type": "union", + "subTypes": [ + { + "type": "array", + "elemType": { + "type": "object", + "name": "AMREntry", + "properties": [ + { + "name": "method", + "type": { + "type": "union", + "name": "AMRMethod", + "subTypes": [ + { + "type": "nameOnly", + "name": "['number']" + }, + null + ] + }, + "comment": { + "shortText": "Authentication method name." + } + }, + { + "name": "timestamp", + "type": "[Circular]", + "comment": { + "shortText": "Timestamp when the method was successfully used. Represents number of\nseconds since 1st January 1970 (UNIX epoch) in UTC." + } + } + ] + } + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "comment": { + "shortText": "A list of all authentication methods attached to this session. Use\nthe information here to detect the last time a user verified a\nfactor, for example if implementing a step-up scenario.\n\nSupports both RFC-8176 compliant format (string[]) and detailed format (AMREntry[]).\n- String format: ['password', 'otp'] - RFC-8176 compliant\n- Object format: [{ method: 'password', timestamp: 1234567890 }] - includes timestamps" + } + }, + { + "name": "currentLevel", + "type": { + "type": "union", + "subTypes": [ + { + "type": "union", + "name": "AuthenticatorAssuranceLevels", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + }, + { + "type": "literal", + "value": null + } + ] + }, + "comment": { + "shortText": "Current AAL level of the session." + } + }, + { + "name": "nextLevel", + "type": { + "type": "union", + "subTypes": [ + { + "type": "union", + "name": "AuthenticatorAssuranceLevels", + "subTypes": [ + "[Circular]", + "[Circular]", + null + ] + }, + { + "type": "literal", + "value": null + } + ] + }, + "comment": { + "shortText": "Next possible AAL level for the session. If the next level is higher\nthan the current one, the user should go through MFA." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Returns the Authenticator Assurance Level (AAL) for the active session.\n\n- `aal1` (or `null`) means that the user's identity has been verified only\nwith a conventional login (email+password, OTP, magic link, social login,\netc.).\n- `aal2` means that the user's identity has been verified both with a conventional login and at least one MFA factor.\n\nWhen called without a JWT parameter, this method is fairly quick (microseconds)\nand rarely uses the network. When a JWT is provided (useful in server-side\nenvironments like Edge Functions where no session is stored), this method\nwill make a network request to validate the user and fetch their MFA factors.", + "text": "- Authenticator Assurance Level (AAL) is the measure of the strength of an authentication mechanism.\n- In Supabase, having an AAL of `aal1` refers to having the 1st factor of authentication such as an email and password or OAuth sign-in while `aal2` refers to the 2nd factor of authentication such as a time-based, one-time-password (TOTP) or Phone factor.\n- If the user has a verified factor, the `nextLevel` field will return `aal2`, else, it will return `aal1`.\n- An optional `jwt` parameter can be passed to check the AAL level of a specific JWT instead of the current session.", + "examples": [ + { + "id": "get-the-aal-details-of-a-session", + "name": "Get the AAL details of a session", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.getAuthenticatorAssuranceLevel()\nconst { currentLevel, nextLevel, currentAuthenticationMethods } = data\n```", + "response": "```json\n{\n data: {\n currentLevel: 'aal1',\n nextLevel: 'aal2',\n currentAuthenticationMethods: [\n {\n method: 'password',\n timestamp: 1700000000\n }\n ]\n }\n error: null\n}\n```" + }, + { + "id": "get-the-aal-details-for-a-specific-jwt", + "name": "Get the AAL details for a specific JWT", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.getAuthenticatorAssuranceLevel(jwt)\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueMFAApi.listFactors": { + "name": "@supabase/supabase-js.GoTrueMFAApi.listFactors", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAListFactorsResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data" + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Returns the list of MFA factors enabled for this user." + } + }, + "@supabase/supabase-js.GoTrueMFAApi.unenroll": { + "name": "@supabase/supabase-js.GoTrueMFAApi.unenroll", + "params": [ + { + "name": "params", + "type": { + "name": "MFAUnenrollParams", + "type": "object", + "properties": [ + { + "name": "factorId", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "ID of the factor being unenrolled." + } + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAUnenrollResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "type": "object", + "properties": [ + { + "name": "id", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "ID of the factor that was successfully unenrolled." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Unenroll removes a MFA factor.\nA user has to have an `aal2` authenticator level in order to unenroll a `verified` factor.", + "examples": [ + { + "id": "unenroll-a-factor", + "name": "Unenroll a factor", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.unenroll({\n factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',\n})\n```", + "response": "```json\n{\n data: {\n id: ''\n },\n error: null\n}\n```" + } + ] + } + }, + "@supabase/supabase-js.GoTrueMFAApi.verify": { + "name": "@supabase/supabase-js.GoTrueMFAApi.verify", + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAVerifyTOTPParams" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "AuthMFAVerifyResponseData", + "type": "object", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "New access token (JWT) after successful verification." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "Number of seconds in which the access token will expire." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "Refresh token you can use to obtain new access tokens when expired." + } + }, + { + "name": "token_type", + "type": "[Circular]", + "comment": { + "shortText": "Type of token, always `bearer`." + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "Updated user profile." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + }, + "comment": { + "shortText": "Verifies a code against a challenge. The verification code is\nprovided by the user by entering a code seen in their authenticator app.", + "text": "- To verify a challenge, please [create a challenge](/docs/reference/javascript/auth-mfa-challenge) first.", + "examples": [ + { + "id": "verify-a-challenge-for-a-factor", + "name": "Verify a challenge for a factor", + "code": "```js\nconst { data, error } = await supabase.auth.mfa.verify({\n factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',\n challengeId: '4034ae6f-a8ce-4fb5-8ee5-69a5863a7c15',\n code: '123456'\n})\n```", + "response": "```json\n{\n data: {\n access_token: '',\n token_type: 'Bearer',\n expires_in: 3600,\n refresh_token: '',\n user: {\n id: '11111111-1111-1111-1111-111111111111',\n aud: 'authenticated',\n role: 'authenticated',\n email: 'example@email.com',\n email_confirmed_at: '2024-01-01T00:00:00Z',\n phone: '',\n confirmation_sent_at: '2024-01-01T00:00:00Z',\n confirmed_at: '2024-01-01T00:00:00Z',\n last_sign_in_at: '2024-01-01T00:00:00Z',\n app_metadata: {\n provider: 'email',\n providers: [\n \"email\",\n ]\n },\n user_metadata: {},\n identities: [\n {\n \"identity_id\": \"22222222-2222-2222-2222-222222222222\",\n \"id\": \"11111111-1111-1111-1111-111111111111\",\n \"user_id\": \"11111111-1111-1111-1111-111111111111\",\n \"identity_data\": {\n \"email\": \"example@email.com\",\n \"email_verified\": true,\n \"phone_verified\": false,\n \"sub\": \"11111111-1111-1111-1111-111111111111\"\n },\n \"provider\": \"email\",\n \"last_sign_in_at\": \"2024-01-01T00:00:00Z\",\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\",\n \"email\": \"email@example.com\"\n },\n ],\n created_at: '2024-01-01T00:00:00Z',\n updated_at: '2024-01-01T00:00:00Z',\n is_anonymous: false,\n factors: [\n \"id\": '',\n \"friendly_name\": 'Important Auth App',\n \"factor_type\": 'totp',\n \"status\": 'verified',\n \"created_at\": \"2024-01-01T00:00:00Z\",\n \"updated_at\": \"2024-01-01T00:00:00Z\"\n ]\n }\n }\n error: null\n}\n```" + } + ] + }, + "altSignatures": [ + { + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAVerifyPhoneParams" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "AuthMFAVerifyResponseData", + "type": "object", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "New access token (JWT) after successful verification." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "Number of seconds in which the access token will expire." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "Refresh token you can use to obtain new access tokens when expired." + } + }, + { + "name": "token_type", + "type": "[Circular]", + "comment": { + "shortText": "Type of token, always `bearer`." + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "Updated user profile." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + } + }, + { + "params": [ + { + "name": "params", + "type": { + "type": "nameOnly", + "name": "MFAVerifyWebauthnParams" + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "AuthMFAVerifyResponseData", + "type": "object", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "New access token (JWT) after successful verification." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "Number of seconds in which the access token will expire." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "Refresh token you can use to obtain new access tokens when expired." + } + }, + { + "name": "token_type", + "type": "[Circular]", + "comment": { + "shortText": "Type of token, always `bearer`." + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "Updated user profile." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + } + }, + { + "params": [ + { + "name": "params", + "type": { + "type": "union", + "name": "MFAVerifyParams", + "subTypes": [ + { + "type": "nameOnly", + "name": "MFAVerifyTOTPParams" + }, + { + "type": "nameOnly", + "name": "MFAVerifyPhoneParams" + }, + { + "type": "nameOnly", + "name": "MFAVerifyWebauthnParams" + } + ] + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "name": "AuthMFAVerifyResponse", + "subTypes": [ + { + "type": "object", + "properties": [ + { + "name": "data", + "type": { + "name": "AuthMFAVerifyResponseData", + "type": "object", + "properties": [ + { + "name": "access_token", + "type": "[Circular]", + "comment": { + "shortText": "New access token (JWT) after successful verification." + } + }, + { + "name": "expires_in", + "type": "[Circular]", + "comment": { + "shortText": "Number of seconds in which the access token will expire." + } + }, + { + "name": "refresh_token", + "type": "[Circular]", + "comment": { + "shortText": "Refresh token you can use to obtain new access tokens when expired." + } + }, + { + "name": "token_type", + "type": "[Circular]", + "comment": { + "shortText": "Type of token, always `bearer`." + } + }, + { + "name": "user", + "type": { + "type": "object", + "name": "AuthUser", + "properties": [ + { + "name": "action_link", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "app_metadata", + "type": { + "type": "object", + "name": "UserAppMetadata", + "properties": [ + { + "name": "provider", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "The first provider that the user used to sign up with." + } + }, + { + "name": "providers", + "type": { + "type": "array", + "elemType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "A list of all providers that the user has linked to their account." + } + } + ] + } + }, + { + "name": "aud", + "type": "[Circular]" + }, + { + "name": "banned_until", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmation_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "deleted_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_change_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "email_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "factors", + "type": { + "type": "array", + "elemType": { + "type": "union", + "subTypes": [ + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + }, + { + "name": "Factor", + "type": "object", + "properties": [ + { + "name": "created_at", + "type": "[Circular]" + }, + { + "name": "factor_type", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "Type of factor. `totp` and `phone` supported with this version" + } + }, + { + "name": "friendly_name", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Friendly name of the factor, useful to disambiguate between multiple factors." + } + }, + { + "name": "id", + "type": "[Circular]", + "comment": { + "shortText": "ID of the factor." + } + }, + { + "name": "last_challenged_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "status", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]", + "[Circular]" + ] + }, + "comment": { + "shortText": "The verification status of the factor, default is `unverified` after `.enroll()`, then `verified` after the user verifies it with `.verify()`" + } + }, + { + "name": "updated_at", + "type": "[Circular]" + } + ] + } + ] + } + }, + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identities", + "type": { + "type": "array", + "elemType": { + "type": "object", + "name": "UserIdentity", + "properties": [ + { + "name": "created_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "id", + "type": "[Circular]" + }, + { + "name": "identity_data", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "identity_id", + "type": "[Circular]" + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "provider", + "type": "[Circular]" + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_id", + "type": "[Circular]" + } + ] + } + }, + "isOptional": true + }, + { + "name": "invited_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_anonymous", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "is_sso_user", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "last_sign_in_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_email", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "new_phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "phone_confirmed_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "recovery_sent_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "role", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "updated_at", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "user_metadata", + "type": { + "type": "object", + "name": "UserMetadata", + "properties": [] + } + } + ] + }, + "comment": { + "shortText": "Updated user profile." + } + } + ] + } + }, + { + "name": "error", + "type": "[Circular]" + } + ] + }, + { + "type": "object", + "properties": [ + { + "name": "data", + "type": "[Circular]" + }, + { + "name": "error" + } + ] + } + ] + } + } + } + } + ] + }, + "@supabase/supabase-js.WebSocketLike.addEventListener": { + "name": "@supabase/supabase-js.WebSocketLike.addEventListener", + "params": [ + { + "name": "type", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "listener", + "type": { + "type": "nameOnly", + "name": "EventListener" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Registers an event listener on the socket (compatible with browser WebSocket API)." + } + }, + "@supabase/supabase-js.WebSocketLike.close": { + "name": "@supabase/supabase-js.WebSocketLike.close", + "params": [ + { + "name": "code", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "reason", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Closes the socket, optionally providing a close code and reason." + } + }, + "@supabase/supabase-js.WebSocketLike.removeEventListener": { + "name": "@supabase/supabase-js.WebSocketLike.removeEventListener", + "params": [ + { + "name": "type", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "listener", + "type": { + "type": "nameOnly", + "name": "EventListener" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Removes a previously registered event listener." + } + }, + "@supabase/supabase-js.WebSocketLike.send": { + "name": "@supabase/supabase-js.WebSocketLike.send", + "params": [ + { + "name": "data", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "nameOnly", + "name": "ArrayBufferLike" + }, + { + "type": "nameOnly", + "name": "ArrayBufferView" + }, + { + "type": "nameOnly", + "name": "Blob" + } + ] + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "void" + } + }, + "comment": { + "shortText": "Sends data through the socket using the underlying implementation." + } + }, + "@supabase/supabase-js.WebSocketLikeConstructor.constructor": { + "name": "@supabase/supabase-js.WebSocketLikeConstructor.constructor", + "params": [ + { + "name": "address", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "nameOnly", + "name": "URL" + } + ] + } + }, + { + "name": "subprotocols", + "type": { + "type": "union", + "subTypes": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "array", + "elemType": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "object", + "name": "WebSocketLike", + "properties": [ + { + "name": "binaryType", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "bufferedAmount", + "type": { + "type": "intrinsic", + "name": "number" + }, + "isOptional": true + }, + { + "name": "CLOSED", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "CLOSING", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "CONNECTING", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "dispatchEvent", + "type": { + "type": "function", + "params": [ + { + "name": "event", + "type": { + "type": "nameOnly", + "name": "Event" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "boolean" + } + } + }, + "isOptional": true + }, + { + "name": "extensions", + "type": { + "type": "intrinsic", + "name": "string" + }, + "isOptional": true + }, + { + "name": "onclose", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "this", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "ev", + "type": { + "type": "nameOnly", + "name": "CloseEvent" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "any" + } + } + } + ] + } + }, + { + "name": "onerror", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "this", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "ev", + "type": { + "type": "nameOnly", + "name": "Event" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "any" + } + } + } + ] + } + }, + { + "name": "onmessage", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "this", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "ev", + "type": { + "type": "nameOnly", + "name": "MessageEvent" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "any" + } + } + } + ] + } + }, + { + "name": "onopen", + "type": { + "type": "union", + "subTypes": [ + { + "type": "literal", + "value": null + }, + { + "type": "function", + "params": [ + { + "name": "this", + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "name": "ev", + "type": { + "type": "nameOnly", + "name": "Event" + } + } + ], + "ret": { + "type": { + "type": "intrinsic", + "name": "any" + } + } + } + ] + } + }, + { + "name": "OPEN", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "protocol", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "readyState", + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "name": "url", + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + }, + "@supabase/supabase-js.createClient": { + "name": "@supabase/supabase-js.createClient", + "params": [ + { + "name": "supabaseUrl", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "supabaseKey", + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "name": "options", + "type": { + "name": "SupabaseClientOptions", + "type": "object", + "properties": [ + { + "name": "accessToken", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + } + } + } + }, + "isOptional": true, + "comment": { + "shortText": "Optional function for using a third-party authentication system with\nSupabase. The function should return an access token or ID token (JWT) by\nobtaining it from the third-party auth SDK. Note that this\nfunction may be called concurrently and many times. Use memoization and\nlocking techniques if this is not supported by the SDKs.\n\nWhen set, the `auth` namespace of the Supabase client cannot be used.\nCreate another client if you wish to use Supabase Auth and third-party\nauthentications concurrently in the same application." + } + }, + { + "name": "auth", + "type": { + "type": "object", + "properties": [ + { + "name": "autoRefreshToken", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Automatically refreshes the token for logged-in users. Defaults to true." + } + }, + { + "name": "debug", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['debug']" + }, + "isOptional": true, + "comment": { + "shortText": "If debug messages for authentication client are emitted. Can be used to inspect the behavior of the library." + } + }, + { + "name": "detectSessionInUrl", + "type": { + "type": "union", + "subTypes": [ + "[Circular]", + { + "type": "function", + "params": [ + { + "name": "url", + "type": { + "type": "nameOnly", + "name": "URL" + } + }, + { + "name": "params", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + } + } + ], + "ret": { + "type": "[Circular]" + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Detect a session from the URL. Used for OAuth login callbacks. Defaults to true.\n\nCan be set to a function to provide custom logic for determining if a URL contains\na Supabase auth callback. The function receives the current URL and parsed parameters,\nand should return true if the URL should be processed as a Supabase auth callback.\n\nThis is useful when your app uses other OAuth providers (e.g., Facebook Login) that\nalso return access_token in the URL fragment, which would otherwise be incorrectly\nintercepted by Supabase Auth.", + "examples": [ + { + "id": "with-custom-detection-logic", + "name": "With custom detection logic", + "code": "```ts\ndetectSessionInUrl: (url, params) => {\n // Ignore Facebook OAuth redirects\n if (url.pathname === '/facebook/redirect') return false\n // Use default detection for other URLs\n return Boolean(params.access_token || params.error_description)\n}\n```" + } + ] + } + }, + { + "name": "experimental", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['experimental']" + }, + "isOptional": true, + "comment": { + "shortText": "Opt-in flags for experimental features. These APIs may change without\nnotice and are disabled by default.", + "tags": [ + { + "tag": "experimental", + "text": "" + } + ] + } + }, + { + "name": "flowType", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['flowType']" + }, + "isOptional": true, + "comment": { + "shortText": "OAuth flow to use - defaults to implicit flow. PKCE is recommended for mobile and server-side applications." + } + }, + { + "name": "lock", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['lock']" + }, + "isOptional": true, + "comment": { + "shortText": "Provide your own locking mechanism based on the environment. By default\nthe auth client coordinates refreshes itself and the server resolves\ncross-tab races. Passing a custom `lock` opts into a legacy path that\nwraps every auth operation in your supplied lock." + } + }, + { + "name": "lockAcquireTimeout", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['lockAcquireTimeout']" + }, + "isOptional": true, + "comment": { + "shortText": "Maximum time in milliseconds to wait for acquiring the custom lock\nsupplied via `lock`. Only consulted when a custom `lock` is passed." + } + }, + { + "name": "persistSession", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Whether to persist a logged-in session to storage. Defaults to true." + } + }, + { + "name": "skipAutoInitialize", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['skipAutoInitialize']" + }, + "isOptional": true, + "comment": { + "shortText": "If true, skips automatic initialization in the auth client constructor.\nUseful for SSR contexts where initialization timing must be controlled to\nprevent race conditions with HTTP response generation." + } + }, + { + "name": "storage", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['storage']" + }, + "isOptional": true, + "comment": { + "shortText": "A storage provider. Used to store the logged-in session." + } + }, + { + "name": "storageKey", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Optional key name used for storing tokens in local storage." + } + }, + { + "name": "throwOnError", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['throwOnError']" + }, + "isOptional": true, + "comment": { + "shortText": "If there is an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response." + } + }, + { + "name": "userStorage", + "type": { + "type": "nameOnly", + "name": "SupabaseAuthClientOptions['userStorage']" + }, + "isOptional": true, + "comment": { + "shortText": "A storage provider to store the user profile separately from the session.\nUseful when you need to store the session information in cookies,\nwithout bloating the data with the redundant user object.", + "tags": [ + { + "tag": "experimental", + "text": "" + } + ] + } + } + ] + }, + "isOptional": true + }, + { + "name": "db", + "type": { + "type": "object", + "properties": [ + { + "name": "schema", + "type": { + "type": "nameOnly", + "name": "SchemaName" + }, + "isOptional": true + }, + { + "name": "timeout", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Optional timeout in milliseconds for PostgREST requests.\nWhen set, requests will automatically abort after this duration to prevent indefinite hangs.", + "examples": [ + { + "id": "with-timeout", + "name": "With timeout", + "code": "```ts\nconst supabase = createClient(url, key, {\n db: { timeout: 30000 } // 30 second timeout\n})\n```" + } + ] + } + }, + { + "name": "urlLengthLimit", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Maximum URL length in characters before warnings/errors are triggered.\nDefaults to 8000 characters. Used to provide helpful hints when URLs\nexceed server limits.", + "examples": [ + { + "id": "with-custom-url-length-limit", + "name": "With custom URL length limit", + "code": "```ts\nconst supabase = createClient(url, key, {\n db: { urlLengthLimit: 10000 } // Custom limit\n})\n```" + } + ] + } + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "The Postgres schema which your tables belong to. Must be on the list of exposed schemas in Supabase. Defaults to `public`." + } + }, + { + "name": "global", + "type": { + "type": "object", + "properties": [ + { + "name": "fetch", + "type": { + "type": "nameOnly", + "name": "Fetch" + }, + "isOptional": true, + "comment": { + "shortText": "A custom `fetch` implementation." + } + }, + { + "name": "headers", + "type": { + "type": "record", + "name": "Record", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true, + "comment": { + "shortText": "Optional headers for initializing the client." + } + } + ] + }, + "isOptional": true + }, + { + "name": "realtime", + "type": { + "name": "RealtimeClientOptions", + "type": "object", + "properties": [ + { + "name": "accessToken", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "union", + "subTypes": [ + "[Circular]", + "[Circular]" + ] + } + } + } + }, + "isOptional": true + }, + { + "name": "decode", + "type": { + "type": "nameOnly", + "name": "Decode" + }, + "isOptional": true + }, + { + "name": "disconnectOnEmptyChannelsAfterMs", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "encode", + "type": { + "type": "nameOnly", + "name": "Encode" + }, + "isOptional": true + }, + { + "name": "fetch", + "type": { + "type": "nameOnly", + "name": "Fetch" + }, + "isOptional": true + }, + { + "name": "headers", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "heartbeatCallback", + "type": { + "type": "function", + "params": [ + { + "name": "status", + "type": { + "type": "nameOnly", + "name": "HeartbeatStatus" + } + }, + { + "name": "latency", + "type": "[Circular]", + "isOptional": true + } + ], + "ret": { + "type": "[Circular]" + } + }, + "isOptional": true + }, + { + "name": "heartbeatIntervalMs", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "log_level", + "type": { + "type": "nameOnly", + "name": "LogLevel" + }, + "isOptional": true + }, + { + "name": "logger", + "type": { + "type": "function", + "params": [ + { + "name": "kind", + "type": "[Circular]" + }, + { + "name": "msg", + "type": "[Circular]" + }, + { + "name": "data", + "type": "[Circular]", + "isOptional": true + } + ], + "ret": { + "type": "[Circular]" + } + }, + "isOptional": true + }, + { + "name": "logLevel", + "type": { + "type": "nameOnly", + "name": "LogLevel" + }, + "isOptional": true + }, + { + "name": "params", + "type": { + "type": "index signature", + "keyType": "[Circular]", + "valueType": "[Circular]" + }, + "isOptional": true + }, + { + "name": "reconnectAfterMs", + "type": { + "type": "function", + "params": [ + { + "name": "tries", + "type": "[Circular]" + } + ], + "ret": { + "type": "[Circular]" + } + }, + "isOptional": true + }, + { + "name": "sessionStorage", + "type": { + "type": "nameOnly", + "name": "Storage" + }, + "isOptional": true, + "comment": { + "shortText": "Storage compatible object used by the underlying socket for longpoll fallback history.\nProvide a custom implementation in environments where reading `globalThis.sessionStorage`\nthrows (sandboxed iframes, in-app webviews, \"block third-party storage\" privacy modes).\nDefaults to `globalThis.sessionStorage` when accessible, otherwise an in-memory store." + } + }, + { + "name": "timeout", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "transport", + "type": { + "type": "object", + "name": "WebSocketLikeConstructor", + "properties": [] + }, + "isOptional": true + }, + { + "name": "vsn", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "worker", + "type": "[Circular]", + "isOptional": true + }, + { + "name": "workerUrl", + "type": "[Circular]", + "isOptional": true + } + ] + }, + "isOptional": true, + "comment": { + "shortText": "Options passed to the realtime-js instance" + } + }, + { + "name": "storage", + "type": { + "type": "nameOnly", + "name": "StorageClientOptions" + }, + "isOptional": true + }, + { + "name": "tracePropagation", + "type": { + "type": "union", + "subTypes": [ + { + "type": "object", + "name": "TracePropagationOptions", + "properties": [ + { + "name": "enabled", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Enable trace propagation. Disabled by default.\n\nWhen enabled, automatically detects and propagates active trace context\nfrom the OpenTelemetry API to outgoing Supabase requests. Trace context\nis only propagated to Supabase domains (`*.supabase.co`, `*.supabase.in`,\n`localhost`) for security — third-party hosts never receive trace headers.", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\nconst supabase = createClient(url, key, {\n tracePropagation: { enabled: true },\n})\n```" + } + ] + } + }, + { + "name": "respectSamplingDecision", + "type": "[Circular]", + "isOptional": true, + "comment": { + "shortText": "Respect upstream sampling decisions.\n\nWhen true (the default), trace context is not propagated if the upstream\ntrace indicates non-sampling (sampled flag = `0` in the `traceparent`\nheader). This avoids overhead when traces are being recorded but dropped.\n\nSet to `false` to always propagate, regardless of the sampling decision\n— useful when you want every Supabase request tagged with a `trace_id`\nfor log correlation, even if the trace itself will not be exported.", + "examples": [ + { + "id": "always-propagate-ignore-sampling", + "name": "Always propagate, ignore sampling", + "code": "```ts\nconst supabase = createClient(url, key, {\n tracePropagation: { enabled: true, respectSamplingDecision: false },\n})\n```" + } + ] + } + } + ] + }, + "[Circular]" + ] + }, + "isOptional": true, + "comment": { + "shortText": "Enable OpenTelemetry / W3C trace context propagation to Supabase services.\n\nDisabled by default. Pass `true` for the common case (auto-detect an\nactive OpenTelemetry context and inject `traceparent` / `tracestate` /\n`baggage` headers) or an object for fine-grained control.\n\nRequires `@opentelemetry/api` to be installed in your application; if\nnot present, the SDK silently no-ops. Trace headers are only attached\nto requests targeting Supabase domains, so third-party hosts called\nthrough a custom `fetch` are never tagged.\n\nThe resulting `trace_id` appears in Supabase logs (API Gateway, Edge\nFunctions), letting you correlate client-side spans with server-side\nlog entries — including logs forwarded via Log Drains.", + "examples": [ + { + "id": "shorthand-opt-in-with-defaults", + "name": "Shorthand — opt in with defaults", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient(url, key, { tracePropagation: true })\n```" + }, + { + "id": "with-an-active-opentelemetry-span", + "name": "With an active OpenTelemetry span", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\nimport { trace } from '@opentelemetry/api'\n\nconst supabase = createClient(url, key, { tracePropagation: true })\nconst tracer = trace.getTracer('my-app')\n\nawait tracer.startActiveSpan('fetch-users', async (span) => {\n // Request carries the active trace context.\n const { data, error } = await supabase.from('users').select('*')\n span.end()\n})\n```" + }, + { + "id": "advanced-always-propagate-even-for-non-sampled-traces", + "name": "Advanced — always propagate, even for non-sampled traces", + "code": "```ts\nconst supabase = createClient(url, key, {\n tracePropagation: { enabled: true, respectSamplingDecision: false },\n})\n```" + } + ] + } + } + ] + }, + "isOptional": true + } + ], + "ret": { + "type": { + "type": "nameOnly", + "name": "SupabaseClient" + } + }, + "comment": { + "shortText": "Creates a new Supabase Client.", + "examples": [ + { + "id": "creating-a-supabase-client", + "name": "Creating a Supabase client", + "code": "```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')\nconst { data, error } = await supabase.from('profiles').select('*')\n```" + } + ] + } + }, + "@supabase/supabase-js.isAuthApiError": { + "name": "@supabase/supabase-js.isAuthApiError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + }, + "@supabase/supabase-js.isAuthError": { + "name": "@supabase/supabase-js.isAuthError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + }, + "@supabase/supabase-js.isAuthImplicitGrantRedirectError": { + "name": "@supabase/supabase-js.isAuthImplicitGrantRedirectError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ] + }, + "@supabase/supabase-js.isAuthPKCECodeVerifierMissingError": { + "name": "@supabase/supabase-js.isAuthPKCECodeVerifierMissingError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + }, + "@supabase/supabase-js.isAuthRefreshDiscardedError": { + "name": "@supabase/supabase-js.isAuthRefreshDiscardedError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + }, + "@supabase/supabase-js.isAuthRetryableFetchError": { + "name": "@supabase/supabase-js.isAuthRetryableFetchError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + }, + "@supabase/supabase-js.isAuthSessionMissingError": { + "name": "@supabase/supabase-js.isAuthSessionMissingError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "any" + } + } + ] + }, + "@supabase/supabase-js.isAuthWeakPasswordError": { + "name": "@supabase/supabase-js.isAuthWeakPasswordError", + "params": [ + { + "name": "error", + "type": { + "type": "intrinsic", + "name": "unknown" + } + } + ] + }, + "@supabase/supabase-js.navigatorLock": { + "name": "@supabase/supabase-js.navigatorLock", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Name of the lock to be acquired." + } + }, + { + "name": "acquireTimeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "If negative, no timeout. If 0 an error is thrown if\n the lock can't be acquired without waiting. If positive, the lock acquire\n will time out after so many milliseconds. An error is\n a timeout if it has `isAcquireTimeout` set to true." + } + }, + { + "name": "fn", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "R" + } + } + } + }, + "comment": { + "shortText": "The operation to run once the lock is acquired." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "R" + } + } + }, + "comment": { + "shortText": "Implements a global exclusive lock using the Navigator LockManager API. It\nis available on all browsers released after 2022-03-15 with Safari being the\nlast one to release support. If the API is not available, this function will\nthrow. Make sure you check availablility before configuring GoTrueClient.\n\nYou can turn on debugging by setting the `supabase.gotrue-js.locks.debug`\nlocal storage item to `true`.\n\nInternals:\n\nSince the LockManager API does not preserve stack traces for the async\nfunction passed in the `request` method, a trick is used where acquiring the\nlock releases a previously started promise to run the operation in the `fn`\nfunction. The lock waits for that promise to finish (with or without error),\nwhile the function will finally wait for the result anyway." + } + }, + "@supabase/supabase-js.processLock": { + "name": "@supabase/supabase-js.processLock", + "params": [ + { + "name": "name", + "type": { + "type": "intrinsic", + "name": "string" + }, + "comment": { + "shortText": "Name of the lock to be acquired." + } + }, + { + "name": "acquireTimeout", + "type": { + "type": "intrinsic", + "name": "number" + }, + "comment": { + "shortText": "If negative, no timeout. If 0 an error is thrown if\n the lock can't be acquired without waiting. If positive, the lock acquire\n will time out after so many milliseconds. An error is\n a timeout if it has `isAcquireTimeout` set to true." + } + }, + { + "name": "fn", + "type": { + "type": "function", + "params": [], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "R" + } + } + } + }, + "comment": { + "shortText": "The operation to run once the lock is acquired." + } + } + ], + "ret": { + "type": { + "type": "promise", + "name": "Promise", + "awaited": { + "type": "nameOnly", + "name": "R" + } + } + }, + "comment": { + "shortText": "Implements a global exclusive lock that works only in the current process.\nUseful for environments like React Native or other non-browser\nsingle-process (i.e. no concept of \"tabs\") environments.\n\nUse #navigatorLock in browser environments.", + "examples": [ + { + "id": "example-1", + "name": "Example 1", + "code": "```ts\nawait processLock('migrate', 5000, async () => {\n await runMigration()\n})\n```" + } + ] + } + } + }, + "variables": { + "@supabase/auth-js.AuthAdminApi": { + "name": "@supabase/auth-js.AuthAdminApi", + "isConst": true + }, + "@supabase/auth-js.AuthClient": { + "name": "@supabase/auth-js.AuthClient", + "isConst": true + }, + "@supabase/auth-js.lockInternals": { + "name": "@supabase/auth-js.lockInternals", + "type": { + "type": "object", + "properties": [ + { + "name": "debug", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "comment": { + "shortText": "", + "tags": [ + { + "tag": "experimental", + "text": "" + } + ] + } + } + ] + }, + "comment": { + "shortText": "", + "tags": [ + { + "tag": "experimental", + "text": "" + } + ] + }, + "isConst": true + }, + "@supabase/auth-js.SIGN_OUT_SCOPES": { + "name": "@supabase/auth-js.SIGN_OUT_SCOPES", + "isConst": true + }, + "@supabase/postgrest-js.default": { + "name": "@supabase/postgrest-js.default", + "type": { + "type": "object", + "properties": [ + { + "name": "PostgrestBuilder" + }, + { + "name": "PostgrestClient" + }, + { + "name": "PostgrestError" + }, + { + "name": "PostgrestFilterBuilder" + }, + { + "name": "PostgrestQueryBuilder" + }, + { + "name": "PostgrestTransformBuilder" + } + ] + }, + "isConst": false + }, + "@supabase/realtime-js.REALTIME_CHANNEL_STATES": { + "name": "@supabase/realtime-js.REALTIME_CHANNEL_STATES", + "type": { + "type": "object", + "properties": [ + { + "name": "closed", + "type": { + "type": "literal", + "value": "closed" + } + }, + { + "name": "errored", + "type": { + "type": "literal", + "value": "errored" + } + }, + { + "name": "joined", + "type": { + "type": "literal", + "value": "joined" + } + }, + { + "name": "joining", + "type": { + "type": "literal", + "value": "joining" + } + }, + { + "name": "leaving", + "type": { + "type": "literal", + "value": "leaving" + } + } + ] + }, + "isConst": true + }, + "@supabase/supabase-js.cors.corsHeaders": { + "name": "@supabase/supabase-js.cors.corsHeaders", + "type": { + "type": "record", + "name": "CorsHeaders", + "keyType": { + "type": "intrinsic", + "name": "string" + }, + "valueType": { + "type": "intrinsic", + "name": "string" + } + }, + "comment": { + "shortText": "Default CORS headers for Supabase Edge Functions.\n\nIncludes all headers sent by Supabase client libraries and allows all standard HTTP methods.\nUse this for simple CORS configurations with wildcard origin.", + "examples": [ + { + "id": "basic-usage", + "name": "Basic usage", + "code": "```typescript\nimport { corsHeaders } from '@supabase/supabase-js/cors'\n\nDeno.serve(async (req) => {\n if (req.method === 'OPTIONS') {\n return new Response('ok', { headers: corsHeaders })\n }\n\n return new Response(\n JSON.stringify({ data: 'Hello' }),\n { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n})\n```" + } + ] + }, + "isConst": true + }, + "@supabase/supabase-js.AuthAdminApi": { + "name": "@supabase/supabase-js.AuthAdminApi", + "isConst": true + }, + "@supabase/supabase-js.AuthClient": { + "name": "@supabase/supabase-js.AuthClient", + "isConst": true + }, + "@supabase/supabase-js.lockInternals": { + "name": "@supabase/supabase-js.lockInternals", + "type": { + "type": "object", + "properties": [ + { + "name": "debug", + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "comment": { + "shortText": "", + "tags": [ + { + "tag": "experimental", + "text": "" + } + ] + } + } + ] + }, + "comment": { + "shortText": "", + "tags": [ + { + "tag": "experimental", + "text": "" + } + ] + }, + "isConst": true + }, + "@supabase/supabase-js.REALTIME_CHANNEL_STATES": { + "name": "@supabase/supabase-js.REALTIME_CHANNEL_STATES", + "type": { + "type": "object", + "properties": [ + { + "name": "closed", + "type": { + "type": "literal", + "value": "closed" + } + }, + { + "name": "errored", + "type": { + "type": "literal", + "value": "errored" + } + }, + { + "name": "joined", + "type": { + "type": "literal", + "value": "joined" + } + }, + { + "name": "joining", + "type": { + "type": "literal", + "value": "joining" + } + }, + { + "name": "leaving", + "type": { + "type": "literal", + "value": "leaving" + } + } + ] + }, + "isConst": true + }, + "@supabase/supabase-js.SIGN_OUT_SCOPES": { + "name": "@supabase/supabase-js.SIGN_OUT_SCOPES", + "isConst": true + } + } + } +} \ No newline at end of file diff --git a/apps/docs/scripts/build-reference-content.test.ts b/apps/docs/scripts/build-reference-content.test.ts index 0fa79f9f9a6..deaa4afdd74 100644 --- a/apps/docs/scripts/build-reference-content.test.ts +++ b/apps/docs/scripts/build-reference-content.test.ts @@ -10,6 +10,11 @@ import { collectReferenceContent } from './build-reference-content' * sees. When the supabase-js `make` workflow lands a new release in * `spec/reference/javascript/v2/`, re-run with `--update` to refresh the * baseline as part of the same PR. + * + * Serializes to a JSON string first so vitest's `pretty-format` serializer + * doesn't collapse deep / cyclic structures (typeSpec contains + * self-referencing builder types) into `[Object]` placeholders — which would + * make param renames, signature changes, and JSDoc edits invisible. */ describe('build-reference-content — javascript/v2', () => { it('matches snapshot', async () => { @@ -17,6 +22,15 @@ describe('build-reference-content — javascript/v2', () => { 'javascript', 'v2' ) - expect({ bySlug, flat, sections, functionsList, typeSpec }).toMatchSnapshot() + const seen = new WeakSet() + const breakCycles = (_key: string, value: unknown) => { + if (value && typeof value === 'object') { + if (seen.has(value as object)) return '[Circular]' + seen.add(value as object) + } + return value + } + const json = JSON.stringify({ bySlug, flat, sections, functionsList, typeSpec }, breakCycles, 2) + await expect(json).toMatchFileSnapshot('./__snapshots__/build-reference-content.v2.json') }) }) From adbd3c3d2255572f78e07c7ab2142c4c9eb95054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Pozo?= Date: Mon, 8 Jun 2026 12:32:15 -0500 Subject: [PATCH 038/134] docs: migrate Edge Functions guides to @supabase/server (COM-269) (#46656) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What Migrates the Edge Functions **documentation** from the legacy `Deno.serve` + manual `createClient` pattern to the [`@supabase/server`](https://github.com/supabase/server) `withSupabase` wrapper. This is the part of [COM-269](https://linear.app/supabase/issue/COM-269) that AI coding assistants index, so it's split out to ship first; the standalone `examples/` functions follow in a second PR. ## Canonical pattern ```ts import { withSupabase } from 'npm:@supabase/server@1' export default { fetch: withSupabase({ auth: 'user' }, async (req, ctx) => { const { data } = await ctx.supabase.from('countries').select('*') return Response.json({ data }) }), } ``` - `export default { fetch }` object shape (not `Deno.serve`, not a bare default export), versioned `npm:@supabase/server@1`. - `auth` mode picks the caller: `user` → `ctx.supabase` (RLS); `secret`/`publishable`/`none` → set `verify_jwt = false`, `secret` uses `ctx.supabaseAdmin`. - `Response.json(...)` over `new Response(JSON.stringify(...))`. ## Changes - **AI prompt** (`examples/prompts/edge-functions.md`) — rewritten to lead with `withSupabase` as the default; `auth`-mode table; `@supabase/server@1`. Highest AI-indexing impact. - **connect-to-postgres** — "Using supabase-js" now uses `ctx.supabase` (+ its CodeSample deps `postgres-on-the-edge`, `drizzle`). - **Example pages** — semantic-search, push-notifications, amazon-bedrock, cloudflare-turnstile, og-image, send-emails, slack-bot-mention, auth-send-email-hook. - **Guides** — ai-models, background-tasks, routing (+ `restful-tasks` dep), kysely-postgres, sentry-monitoring, upstash-redis, elevenlabs ×2, websockets, cors (reframed: CORS is automatic with `withSupabase`). ## Notable fixes - **websockets**: the JWT-auth examples had a latent bug — handler wasn't `async` and called `getClaims()` without the extracted token. Now `await supabase.auth.getUser(jwt)`. (`withSupabase` can't authenticate WebSocket clients since they can't send headers — noted in the page.) - **restful-tasks**: fixed a broken `npm:supabase-js` import → `npm:@supabase/supabase-js`. ## Follow-ups (not in this PR) - The ~42 standalone `examples/` edge functions → second PR. - A dedicated `withSupabase` intro page (today it's only documented inside the auth-framed "Securing Edge Functions" page). - `.claude/skills/supabase-server/SKILL.md` is stale (`allow:` vs `auth:`). ## Summary by CodeRabbit * **Documentation** * Updated Edge Function examples to the modern withSupabase + exported fetch handler pattern across guides and examples. * Standardized JSON response/error handling (uses built-in JSON helpers) and preserved streaming/SSE behaviors where applicable. * Clarified auth modes, context clients (user vs admin), and automatic CORS handling; removed manual preflight boilerplate. * Updated local serve/deploy instructions to include --no-verify-jwt for relevant examples. --- .../content/guides/functions/ai-models.mdx | 238 +++++++++--------- .../guides/functions/background-tasks.mdx | 34 ++- .../guides/functions/connect-to-postgres.mdx | 37 ++- apps/docs/content/guides/functions/cors.mdx | 55 ++-- .../amazon-bedrock-image-generator.mdx | 134 +++++----- ...uth-send-email-hook-react-email-resend.mdx | 128 +++++----- .../examples/cloudflare-turnstile.mdx | 56 ++--- .../elevenlabs-generate-speech-stream.mdx | 156 ++++++------ .../examples/elevenlabs-transcribe-speech.mdx | 47 ++-- .../guides/functions/examples/og-image.mdx | 7 +- .../functions/examples/push-notifications.mdx | 146 +++++------ .../functions/examples/semantic-search.mdx | 88 ++++--- .../guides/functions/examples/send-emails.mdx | 20 +- .../functions/examples/sentry-monitoring.mdx | 37 +-- .../functions/examples/slack-bot-mention.mdx | 53 ++-- .../functions/examples/upstash-redis.mdx | 60 ++--- .../guides/functions/kysely-postgres.mdx | 54 ++-- .../docs/content/guides/functions/routing.mdx | 106 ++++---- .../content/guides/functions/websockets.mdx | 167 ++++++------ .../supabase/functions/drizzle/index.ts | 11 +- .../functions/postgres-on-the-edge/index.ts | 60 ++--- .../supabase/functions/restful-tasks/index.ts | 126 ++++------ examples/prompts/edge-functions.md | 127 +++++++--- 23 files changed, 1013 insertions(+), 934 deletions(-) diff --git a/apps/docs/content/guides/functions/ai-models.mdx b/apps/docs/content/guides/functions/ai-models.mdx index f31c01ed897..b349cfe424f 100644 --- a/apps/docs/content/guides/functions/ai-models.mdx +++ b/apps/docs/content/guides/functions/ai-models.mdx @@ -73,19 +73,18 @@ Generate text embeddings using the built-in [`gte-small`](https://huggingface.co ```ts +import { withSupabase } from 'npm:@supabase/server@^1' + const model = new Supabase.ai.Session('gte-small') -Deno.serve(async (req: Request) => { - const params = new URL(req.url).searchParams - const input = params.get('input') - const output = await model.run(input, { mean_pool: true, normalize: true }) - return new Response(JSON.stringify(output), { - headers: { - 'Content-Type': 'application/json', - Connection: 'keep-alive', - }, - }) -}) +export default { + fetch: withSupabase({ auth: 'publishable' }, async (req, ctx) => { + const params = new URL(req.url).searchParams + const input = params.get('input') + const output = await model.run(input, { mean_pool: true, normalize: true }) + return Response.json(output) + }), +} ``` --- @@ -157,42 +156,46 @@ We are progressively rolling out support for the hosted solution. To sign up for ```ts supabase/functions/ollama-test/index.ts import 'jsr:@supabase/functions-js/edge-runtime.d.ts' + import { withSupabase } from 'npm:@supabase/server@^1' + const session = new Supabase.ai.Session('mistral') - Deno.serve(async (req: Request) => { - const params = new URL(req.url).searchParams - const prompt = params.get('prompt') ?? '' + export default { + fetch: withSupabase({ auth: 'publishable' }, async (req, ctx) => { + const params = new URL(req.url).searchParams + const prompt = params.get('prompt') ?? '' - // Get the output as a stream - const output = await session.run(prompt, { stream: true }) + // Get the output as a stream + const output = await session.run(prompt, { stream: true }) - const headers = new Headers({ - 'Content-Type': 'text/event-stream', - Connection: 'keep-alive', - }) + const headers = new Headers({ + 'Content-Type': 'text/event-stream', + Connection: 'keep-alive', + }) - // Create a stream - const stream = new ReadableStream({ - async start(controller) { - const encoder = new TextEncoder() + // Create a stream + const stream = new ReadableStream({ + async start(controller) { + const encoder = new TextEncoder() - try { - for await (const chunk of output) { - controller.enqueue(encoder.encode(chunk.response ?? '')) + try { + for await (const chunk of output) { + controller.enqueue(encoder.encode(chunk.response ?? '')) + } + } catch (err) { + console.error('Stream error:', err) + } finally { + controller.close() } - } catch (err) { - console.error('Stream error:', err) - } finally { - controller.close() - } - }, - }) + }, + }) - // Return the stream to the user - return new Response(stream, { - headers, - }) - }) + // Return the stream to the user + return new Response(stream, { + headers, + }) + }), + } ``` @@ -201,7 +204,7 @@ We are progressively rolling out support for the hosted solution. To sign up for ```bash - supabase functions serve --env-file supabase/functions/.env + supabase functions serve --no-verify-jwt --env-file supabase/functions/.env ``` @@ -265,36 +268,40 @@ Since Llamafile provides an OpenAI API compatible server, you can either use it ```ts supabase/functions/llamafile-test/index.ts import 'jsr:@supabase/functions-js/edge-runtime.d.ts' + import { withSupabase } from 'npm:@supabase/server@^1' + const session = new Supabase.ai.Session('LLaMA_CPP') - Deno.serve(async (req: Request) => { - const params = new URL(req.url).searchParams - const prompt = params.get('prompt') ?? '' + export default { + fetch: withSupabase({ auth: 'publishable' }, async (req, ctx) => { + const params = new URL(req.url).searchParams + const prompt = params.get('prompt') ?? '' - // Get the output as a stream - const output = await session.run( - { - messages: [ - { - role: 'system', - content: - 'You are LLAMAfile, an AI assistant. Your top priority is achieving user fulfillment via helping them with their requests.', - }, - { - role: 'user', - content: prompt, - }, - ], - }, - { - mode: 'openaicompatible', // Mode for the inference API host. (default: 'ollama') - stream: false, - } - ) + // Get the output as a stream + const output = await session.run( + { + messages: [ + { + role: 'system', + content: + 'You are LLAMAfile, an AI assistant. Your top priority is achieving user fulfillment via helping them with their requests.', + }, + { + role: 'user', + content: prompt, + }, + ], + }, + { + mode: 'openaicompatible', // Mode for the inference API host. (default: 'ollama') + stream: false, + } + ) - console.log('done') - return Response.json(output) - }) + console.log('done') + return Response.json(output) + }), + } ``` @@ -302,7 +309,7 @@ Since Llamafile provides an OpenAI API compatible server, you can either use it ```bash - supabase functions serve --env-file supabase/functions/.env + supabase functions serve --no-verify-jwt --env-file supabase/functions/.env ``` @@ -350,60 +357,63 @@ Since Llamafile provides an OpenAI API compatible server, you can either use it ```ts + import { withSupabase } from 'npm:@supabase/server@^1' import OpenAI from 'https://deno.land/x/openai@v4.53.2/mod.ts' - Deno.serve(async (req) => { - const client = new OpenAI() - const { prompt } = await req.json() - const stream = true + export default { + fetch: withSupabase({ auth: 'publishable' }, async (req, ctx) => { + const client = new OpenAI() + const { prompt } = await req.json() + const stream = true - const chatCompletion = await client.chat.completions.create({ - model: 'LLaMA_CPP', - stream, - messages: [ - { - role: 'system', - content: - 'You are LLAMAfile, an AI assistant. Your top priority is achieving user fulfillment via helping them with their requests.', - }, - { - role: 'user', - content: prompt, - }, - ], - }) - - if (stream) { - const headers = new Headers({ - 'Content-Type': 'text/event-stream', - Connection: 'keep-alive', + const chatCompletion = await client.chat.completions.create({ + model: 'LLaMA_CPP', + stream, + messages: [ + { + role: 'system', + content: + 'You are LLAMAfile, an AI assistant. Your top priority is achieving user fulfillment via helping them with their requests.', + }, + { + role: 'user', + content: prompt, + }, + ], }) - // Create a stream - const stream = new ReadableStream({ - async start(controller) { - const encoder = new TextEncoder() + if (stream) { + const headers = new Headers({ + 'Content-Type': 'text/event-stream', + Connection: 'keep-alive', + }) - try { - for await (const part of chatCompletion) { - controller.enqueue(encoder.encode(part.choices[0]?.delta?.content || '')) + // Create a stream + const stream = new ReadableStream({ + async start(controller) { + const encoder = new TextEncoder() + + try { + for await (const part of chatCompletion) { + controller.enqueue(encoder.encode(part.choices[0]?.delta?.content || '')) + } + } catch (err) { + console.error('Stream error:', err) + } finally { + controller.close() } - } catch (err) { - console.error('Stream error:', err) - } finally { - controller.close() - } - }, - }) + }, + }) - // Return the stream to the user - return new Response(stream, { - headers, - }) - } + // Return the stream to the user + return new Response(stream, { + headers, + }) + } - return Response.json(chatCompletion) - }) + return Response.json(chatCompletion) + }), + } ``` @@ -411,7 +421,7 @@ Since Llamafile provides an OpenAI API compatible server, you can either use it ```bash - supabase functions serve --env-file supabase/functions/.env + supabase functions serve --no-verify-jwt --env-file supabase/functions/.env ``` @@ -455,7 +465,7 @@ Once the function is working locally, it's time to deploy to production. ```bash - supabase functions deploy + supabase functions deploy --no-verify-jwt ``` diff --git a/apps/docs/content/guides/functions/background-tasks.mdx b/apps/docs/content/guides/functions/background-tasks.mdx index 923e70e4a10..adde605ed48 100644 --- a/apps/docs/content/guides/functions/background-tasks.mdx +++ b/apps/docs/content/guides/functions/background-tasks.mdx @@ -19,29 +19,39 @@ This allows you to: You can use `EdgeRuntime.waitUntil(promise)` to explicitly mark background tasks. The Function instance continues to run until the promise provided to `waitUntil` completes. ```ts +import { withSupabase } from 'npm:@supabase/server@^1' + // Mark the asyncLongRunningTask's returned promise as a background task. // ⚠️ We are NOT using `await` because we don't want it to block! EdgeRuntime.waitUntil(asyncLongRunningTask()) -Deno.serve(async (req) => { - return new Response(...) -}) +export default { + fetch: withSupabase({ auth: 'user' }, async (req, ctx) => { + return new Response(...) + }), +} ``` You can call `EdgeRuntime.waitUntil` in the request handler too. This will not block the request. ```ts -Deno.serve(async (req) => { - // Won't block the request, runs in background. - EdgeRuntime.waitUntil(asyncLongRunningTask()) +import { withSupabase } from 'npm:@supabase/server@^1' - return new Response(...) -}) +export default { + fetch: withSupabase({ auth: 'user' }, async (req, ctx) => { + // Won't block the request, runs in background. + EdgeRuntime.waitUntil(asyncLongRunningTask()) + + return new Response(...) + }), +} ``` You can listen to the `beforeunload` event handler to be notified when the Function is about to be shut down. ```tsx +import { withSupabase } from 'npm:@supabase/server@^1' + EdgeRuntime.waitUntil(asyncLongRunningTask()) // Use beforeunload event handler to be notified when function is about to shutdown @@ -50,9 +60,11 @@ addEventListener('beforeunload', (ev) => { // Save state or log the current progress }) -Deno.serve(async (req) => { - return new Response(...) -}) +export default { + fetch: withSupabase({ auth: 'user' }, async (req, ctx) => { + return new Response(...) + }), +} ``` ## Handling errors diff --git a/apps/docs/content/guides/functions/connect-to-postgres.mdx b/apps/docs/content/guides/functions/connect-to-postgres.mdx index 2c99a64fc2c..b3df92c5411 100644 --- a/apps/docs/content/guides/functions/connect-to-postgres.mdx +++ b/apps/docs/content/guides/functions/connect-to-postgres.mdx @@ -13,33 +13,28 @@ You can also use other Postgres clients like [Deno Postgres](https://deno.land/x ## Using supabase-js -The `supabase-js` client handles authorization with Row Level Security and automatically formats responses as JSON. This is the recommended approach for most applications: +The [`withSupabase`](/docs/guides/functions/auth) wrapper from `@supabase/server` hands you a `supabase-js` client (`ctx.supabase`) already scoped to the caller's Row Level Security policies, so you don't manage keys or authorization headers yourself. It also provides `ctx.supabaseAdmin` for privileged operations that bypass Row Level Security. Responses are automatically formatted as JSON. This is the recommended approach for most applications: ```ts index.ts -import { createClient } from 'npm:@supabase/supabase-js@2' +import { withSupabase } from 'npm:@supabase/server@^1' -Deno.serve(async (req) => { - try { - const supabase = createClient( - Deno.env.get('SUPABASE_URL') ?? '', - Deno.env.get('SUPABASE_PUBLISHABLE_KEY') ?? '', - { global: { headers: { Authorization: req.headers.get('Authorization')! } } } - ) +export default { + fetch: withSupabase({ auth: 'user' }, async (req, ctx) => { + try { + // ctx.supabase respects the caller's RLS policies. + // ctx.supabaseAdmin bypasses RLS for privileged operations. + const { data, error } = await ctx.supabase.from('countries').select('*') - const { data, error } = await supabase.from('countries').select('*') + if (error) { + throw error + } - if (error) { - throw error + return Response.json({ data }) + } catch (err) { + return new Response(String(err?.message ?? err), { status: 500 }) } - - return new Response(JSON.stringify({ data }), { - headers: { 'Content-Type': 'application/json' }, - status: 200, - }) - } catch (err) { - return new Response(String(err?.message ?? err), { status: 500 }) - } -}) + }), +} ``` This enables: diff --git a/apps/docs/content/guides/functions/cors.mdx b/apps/docs/content/guides/functions/cors.mdx index 2b48518de9c..420aa5a74aa 100644 --- a/apps/docs/content/guides/functions/cors.mdx +++ b/apps/docs/content/guides/functions/cors.mdx @@ -6,9 +6,24 @@ description: 'Add CORS headers to invoke Edge Functions from the browser.' To invoke edge functions from the browser, you need to handle [CORS Preflight](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request) requests. -See the [example on GitHub](https://github.com/supabase/supabase/blob/master/examples/edge-functions/supabase/functions/browser-with-cors/index.ts). +## Automatic CORS handling -### Recommended setup +The [`withSupabase`](/docs/guides/functions/auth) wrapper handles CORS and preflight (`OPTIONS`) requests for you, so you don't add headers manually: + +```ts index.ts +import { withSupabase } from 'npm:@supabase/server@^1' + +export default { + fetch: withSupabase({ auth: 'user' }, async (req, ctx) => { + const { name } = await req.json() + return Response.json({ message: `Hello ${name}!` }) + }), +} +``` + +## Manual CORS handling + +If your function doesn't use `withSupabase`, add the headers yourself. See the [example on GitHub](https://github.com/supabase/supabase/blob/master/examples/edge-functions/supabase/functions/browser-with-cors/index.ts). @@ -23,34 +38,26 @@ import { corsHeaders } from '@supabase/supabase-js/cors' console.log(`Function "browser-with-cors" up and running!`) -Deno.serve(async (req) => { - // This is needed if you're planning to invoke your function from a browser. - if (req.method === 'OPTIONS') { - return new Response('ok', { headers: corsHeaders }) - } - - try { - const { name } = await req.json() - const data = { - message: `Hello ${name}!`, +export default { + fetch: async (req) => { + // Handle the CORS preflight request. + if (req.method === 'OPTIONS') { + return new Response('ok', { headers: corsHeaders }) } - return new Response(JSON.stringify(data), { - headers: { ...corsHeaders, 'Content-Type': 'application/json' }, - status: 200, - }) - } catch (error) { - return new Response(JSON.stringify({ error: error.message }), { - headers: { ...corsHeaders, 'Content-Type': 'application/json' }, - status: 400, - }) - } -}) + try { + const { name } = await req.json() + return Response.json({ message: `Hello ${name}!` }, { headers: corsHeaders }) + } catch (error) { + return Response.json({ error: error.message }, { status: 400, headers: corsHeaders }) + } + }, +} ``` This approach ensures that when new headers are added to the Supabase SDK, your Edge Functions automatically include them, preventing CORS errors. -#### For versions before 2.95.0 +### For versions before 2.95.0 If you're using `@supabase/supabase-js` before v2.95.0, you'll need to hardcode the CORS headers. Add a `cors.ts` file within a [`_shared` folder](/docs/guides/functions/development-environment#recommended-project-structure): diff --git a/apps/docs/content/guides/functions/examples/amazon-bedrock-image-generator.mdx b/apps/docs/content/guides/functions/examples/amazon-bedrock-image-generator.mdx index 99808e2f6b9..04c258cb300 100644 --- a/apps/docs/content/guides/functions/examples/amazon-bedrock-image-generator.mdx +++ b/apps/docs/content/guides/functions/examples/amazon-bedrock-image-generator.mdx @@ -46,91 +46,83 @@ And add the code to the `index.ts` file: ```ts index.ts // We need to mock the file system for the AWS SDK to work. import { prepareVirtualFile } from 'https://deno.land/x/mock_file@v1.1.2/mod.ts' - import { BedrockRuntimeClient, InvokeModelCommand } from 'npm:@aws-sdk/client-bedrock-runtime' -import { createClient } from 'npm:@supabase/supabase-js' +import { withSupabase } from 'npm:@supabase/server@^1' import { decode } from 'npm:base64-arraybuffer' console.log('Hello from Amazon Bedrock!') -const SUPABASE_PUBLISHABLE_KEYS = JSON.parse(Deno.env.get('SUPABASE_PUBLISHABLE_KEYS')!) +// Called with a publishable key on the `apikey` header. Deploy with `verify_jwt = false`. +export default { + fetch: withSupabase({ auth: 'publishable' }, async (req, ctx) => { + prepareVirtualFile('./aws/config') + prepareVirtualFile('./aws/credentials') -Deno.serve(async (req) => { - prepareVirtualFile('./aws/config') - prepareVirtualFile('./aws/credentials') - - const client = new BedrockRuntimeClient({ - region: Deno.env.get('AWS_DEFAULT_REGION') ?? 'us-west-2', - credentials: { - accessKeyId: Deno.env.get('AWS_ACCESS_KEY_ID') ?? '', - secretAccessKey: Deno.env.get('AWS_SECRET_ACCESS_KEY') ?? '', - sessionToken: Deno.env.get('AWS_SESSION_TOKEN') ?? '', - }, - }) - - const { prompt, seed } = await req.json() - console.log(prompt) - const input = { - contentType: 'application/json', - accept: '*/*', - modelId: 'amazon.titan-image-generator-v1', - body: JSON.stringify({ - taskType: 'TEXT_IMAGE', - textToImageParams: { text: prompt }, - imageGenerationConfig: { - numberOfImages: 1, - quality: 'standard', - cfgScale: 8.0, - height: 512, - width: 512, - seed: seed ?? 0, + const client = new BedrockRuntimeClient({ + region: Deno.env.get('AWS_DEFAULT_REGION') ?? 'us-west-2', + credentials: { + accessKeyId: Deno.env.get('AWS_ACCESS_KEY_ID') ?? '', + secretAccessKey: Deno.env.get('AWS_SECRET_ACCESS_KEY') ?? '', + sessionToken: Deno.env.get('AWS_SESSION_TOKEN') ?? '', }, - }), - } + }) - const command = new InvokeModelCommand(input) - const response = await client.send(command) - console.log(response) - - if (response.$metadata.httpStatusCode === 200) { - const { body, $metadata } = response - - const textDecoder = new TextDecoder('utf-8') - const jsonString = textDecoder.decode(body.buffer) - const parsedData = JSON.parse(jsonString) - console.log(parsedData) - const image = parsedData.images[0] - - const supabaseClient = createClient( - // Supabase API URL - env var exported by default. - Deno.env.get('SUPABASE_URL')!, - // Using the default Supabase API PUB KEY. - // If you want to use a different api key, change 'default' to your preferred key name - SUPABASE_PUBLISHABLE_KEYS['default'] - ) - - const { data: upload, error: uploadError } = await supabaseClient.storage - .from('images') - .upload(`${$metadata.requestId ?? ''}.png`, decode(image), { - contentType: 'image/png', - cacheControl: '3600', - upsert: false, - }) - if (!upload) { - return Response.json(uploadError) + const { prompt, seed } = await req.json() + console.log(prompt) + const input = { + contentType: 'application/json', + accept: '*/*', + modelId: 'amazon.titan-image-generator-v1', + body: JSON.stringify({ + taskType: 'TEXT_IMAGE', + textToImageParams: { text: prompt }, + imageGenerationConfig: { + numberOfImages: 1, + quality: 'standard', + cfgScale: 8.0, + height: 512, + width: 512, + seed: seed ?? 0, + }, + }), } - const { data } = supabaseClient.storage.from('images').getPublicUrl(upload.path!) - return Response.json(data) - } - return Response.json(response) -}) + const command = new InvokeModelCommand(input) + const response = await client.send(command) + console.log(response) + + if (response.$metadata.httpStatusCode === 200) { + const { body, $metadata } = response + + const textDecoder = new TextDecoder('utf-8') + const jsonString = textDecoder.decode(body.buffer) + const parsedData = JSON.parse(jsonString) + console.log(parsedData) + const image = parsedData.images[0] + + const { data: upload, error: uploadError } = await ctx.supabase.storage + .from('images') + .upload(`${$metadata.requestId ?? ''}.png`, decode(image), { + contentType: 'image/png', + cacheControl: '3600', + upsert: false, + }) + if (!upload) { + return Response.json(uploadError) + } + const { data } = ctx.supabase.storage.from('images').getPublicUrl(upload.path!) + return Response.json(data) + } + + return Response.json(response) + }), +} ``` ## Run the function locally 1. Run `supabase start` (see: https://supabase.com/docs/reference/cli/supabase-start) -2. Start with env: `supabase functions serve --env-file supabase/.env` +2. Start with env: `supabase functions serve --no-verify-jwt --env-file supabase/.env` 3. Make an HTTP request: ```bash @@ -146,7 +138,7 @@ Deno.serve(async (req) => { ```bash supabase link -supabase functions deploy amazon-bedrock +supabase functions deploy amazon-bedrock --no-verify-jwt supabase secrets set --env-file supabase/.env ``` diff --git a/apps/docs/content/guides/functions/examples/auth-send-email-hook-react-email-resend.mdx b/apps/docs/content/guides/functions/examples/auth-send-email-hook-react-email-resend.mdx index e21a4dfab24..7b10c3140c6 100644 --- a/apps/docs/content/guides/functions/examples/auth-send-email-hook-react-email-resend.mdx +++ b/apps/docs/content/guides/functions/examples/auth-send-email-hook-react-email-resend.mdx @@ -34,84 +34,80 @@ supabase functions new send-email Paste the following code into the `index.ts` file: ```tsx supabase/functions/send-email/index.ts -import React from 'npm:react@18.3.1' import { Webhook } from 'https://esm.sh/standardwebhooks@1.0.0' -import { Resend } from 'npm:resend@4.0.0' import { renderAsync } from 'npm:@react-email/components@0.0.22' +import { withSupabase } from 'npm:@supabase/server@^1' +import React from 'npm:react@18.3.1' +import { Resend } from 'npm:resend@4.0.0' + import { MagicLinkEmail } from './_templates/magic-link.tsx' const resend = new Resend(Deno.env.get('RESEND_API_KEY') as string) const hookSecret = (Deno.env.get('SEND_EMAIL_HOOK_SECRET') as string).replace('v1,whsec_', '') -Deno.serve(async (req) => { - if (req.method !== 'POST') { - return new Response('not allowed', { status: 400 }) - } - - const payload = await req.text() - const headers = Object.fromEntries(req.headers) - const wh = new Webhook(hookSecret) - try { - const { - user, - email_data: { token, token_hash, redirect_to, email_action_type }, - } = wh.verify(payload, headers) as { - user: { - email: string - } - email_data: { - token: string - token_hash: string - redirect_to: string - email_action_type: string - site_url: string - token_new: string - token_hash_new: string - } +export default { + fetch: withSupabase({ auth: 'none' }, async (req) => { + if (req.method !== 'POST') { + return new Response('not allowed', { status: 400 }) } - const html = await renderAsync( - React.createElement(MagicLinkEmail, { - supabase_url: Deno.env.get('SUPABASE_URL') ?? '', - token, - token_hash, - redirect_to, - email_action_type, + const payload = await req.text() + const headers = Object.fromEntries(req.headers) + const wh = new Webhook(hookSecret) + try { + const { + user, + email_data: { token, token_hash, redirect_to, email_action_type }, + } = wh.verify(payload, headers) as { + user: { + email: string + } + email_data: { + token: string + token_hash: string + redirect_to: string + email_action_type: string + site_url: string + token_new: string + token_hash_new: string + } + } + + const html = await renderAsync( + React.createElement(MagicLinkEmail, { + supabase_url: Deno.env.get('SUPABASE_URL') ?? '', + token, + token_hash, + redirect_to, + email_action_type, + }) + ) + + const { error } = await resend.emails.send({ + from: 'welcome ', + to: [user.email], + subject: 'Supa Custom MagicLink!', + html, }) - ) - - const { error } = await resend.emails.send({ - from: 'welcome ', - to: [user.email], - subject: 'Supa Custom MagicLink!', - html, - }) - if (error) { - throw error - } - } catch (error) { - console.log(error) - return new Response( - JSON.stringify({ - error: { - http_code: error.code, - message: error.message, - }, - }), - { - status: 401, - headers: { 'Content-Type': 'application/json' }, + if (error) { + throw error } - ) - } + } catch (error) { + console.log(error) + return Response.json( + { + error: { + http_code: error.code, + message: error.message, + }, + }, + { status: 401 } + ) + } - const responseHeaders = new Headers() - responseHeaders.set('Content-Type', 'application/json') - return new Response(JSON.stringify({}), { - status: 200, - headers: responseHeaders, - }) -}) + return Response.json({}) + }), +} ``` ### 3. Create React Email templates diff --git a/apps/docs/content/guides/functions/examples/cloudflare-turnstile.mdx b/apps/docs/content/guides/functions/examples/cloudflare-turnstile.mdx index 8d6c208e3c3..f28412b1025 100644 --- a/apps/docs/content/guides/functions/examples/cloudflare-turnstile.mdx +++ b/apps/docs/content/guides/functions/examples/cloudflare-turnstile.mdx @@ -23,7 +23,7 @@ supabase functions new cloudflare-turnstile And add the code to the `index.ts` file: ```ts index.ts -import { corsHeaders } from '@supabase/supabase-js/cors' // v2.95.0+ +import { withSupabase } from 'npm:@supabase/server@^1' console.log('Hello from Cloudflare Trunstile!') @@ -31,36 +31,34 @@ function ips(req: Request) { return req.headers.get('x-forwarded-for')?.split(/\s*,\s*/) } -Deno.serve(async (req) => { - // This is needed if you're planning to invoke your function from a browser. - if (req.method === 'OPTIONS') { - return new Response('ok', { headers: corsHeaders }) - } +// `withSupabase` handles CORS and preflight requests for you. +export default { + fetch: withSupabase({ auth: 'none' }, async (req) => { + const { token } = await req.json() + const clientIps = ips(req) || [''] + const ip = clientIps[0] - const { token } = await req.json() - const clientIps = ips(req) || [''] - const ip = clientIps[0] + // Validate the token by calling the + // "/siteverify" API endpoint. + let formData = new FormData() + formData.append('secret', Deno.env.get('CLOUDFLARE_SECRET_KEY') ?? '') + formData.append('response', token) + formData.append('remoteip', ip) - // Validate the token by calling the - // "/siteverify" API endpoint. - let formData = new FormData() - formData.append('secret', Deno.env.get('CLOUDFLARE_SECRET_KEY') ?? '') - formData.append('response', token) - formData.append('remoteip', ip) + const url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify' + const result = await fetch(url, { + body: formData, + method: 'POST', + }) - const url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify' - const result = await fetch(url, { - body: formData, - method: 'POST', - }) - - const outcome = await result.json() - console.log(outcome) - if (outcome.success) { - return new Response('success', { headers: corsHeaders }) - } - return new Response('failure', { headers: corsHeaders }) -}) + const outcome = await result.json() + console.log(outcome) + if (outcome.success) { + return new Response('success') + } + return new Response('failure') + }), +} ``` ## Deploy the server-side validation Edge Functions @@ -68,7 +66,7 @@ Deno.serve(async (req) => { - https://developers.cloudflare.com/turnstile/get-started/server-side-validation/ ```bash -supabase functions deploy cloudflare-turnstile +supabase functions deploy cloudflare-turnstile --no-verify-jwt supabase secrets set CLOUDFLARE_SECRET_KEY=your_secret_key ``` diff --git a/apps/docs/content/guides/functions/examples/elevenlabs-generate-speech-stream.mdx b/apps/docs/content/guides/functions/examples/elevenlabs-generate-speech-stream.mdx index 6ea7ac92d9c..d6ef95ec477 100644 --- a/apps/docs/content/guides/functions/examples/elevenlabs-generate-speech-stream.mdx +++ b/apps/docs/content/guides/functions/examples/elevenlabs-generate-speech-stream.mdx @@ -100,95 +100,91 @@ In your newly created `supabase/functions/text-to-speech/index.ts` file, add the ```ts supabase/functions/text-to-speech/index.ts // Setup type definitions for built-in Supabase Runtime APIs import 'jsr:@supabase/functions-js/edge-runtime.d.ts' -import { createClient } from 'npm:@supabase/supabase-js@2' + +import { withSupabase } from 'npm:@supabase/server@^1' import { ElevenLabsClient } from 'npm:elevenlabs@1.52.0' import * as hash from 'npm:object-hash' -const SUPABASE_SECRET_KEYS = JSON.parse(Deno.env.get('SUPABASE_SECRET_KEYS')!) - -// If you want to use a different api key, change 'default' to your preferred key name -const supabase = createClient(Deno.env.get('SUPABASE_URL')!, SUPABASE_SECRET_KEYS['default']) - const client = new ElevenLabsClient({ apiKey: Deno.env.get('ELEVENLABS_API_KEY'), }) -// Upload audio to Supabase Storage in a background task -async function uploadAudioToStorage(stream: ReadableStream, requestHash: string) { - const { data, error } = await supabase.storage - .from('audio') - .upload(`${requestHash}.mp3`, stream, { - contentType: 'audio/mp3', - }) +// Deploy with verify_jwt = false +// Open endpoint for testing. In production, implement an authorization layer in the handler or switch the auth mode. +export default { + fetch: withSupabase({ auth: 'none' }, async (req, ctx) => { + // Upload audio to Supabase Storage in a background task + async function uploadAudioToStorage(stream: ReadableStream, requestHash: string) { + const { data, error } = await ctx.supabaseAdmin.storage + .from('audio') + .upload(`${requestHash}.mp3`, stream, { + contentType: 'audio/mp3', + }) - console.log('Storage upload result', { data, error }) + console.log('Storage upload result', { data, error }) + } + + // To secure your function for production, you can for example validate the request origin, + // or append a user access token and validate it with Supabase Auth. + console.log('Request origin', req.headers.get('host')) + const url = new URL(req.url) + const params = new URLSearchParams(url.search) + const text = params.get('text') + const voiceId = params.get('voiceId') ?? 'JBFqnCBsd6RMkjVDRZzb' + + const requestHash = hash.MD5({ text, voiceId }) + console.log('Request hash', requestHash) + + // Check storage for existing audio file + const { data } = await ctx.supabaseAdmin.storage + .from('audio') + .createSignedUrl(`${requestHash}.mp3`, 60) + + if (data) { + console.log('Audio file found in storage', data) + const storageRes = await fetch(data.signedUrl) + if (storageRes.ok) return storageRes + } + + if (!text) { + return Response.json({ error: 'Text parameter is required' }, { status: 400 }) + } + + try { + console.log('ElevenLabs API call') + const response = await client.textToSpeech.convertAsStream(voiceId, { + output_format: 'mp3_44100_128', + model_id: 'eleven_multilingual_v2', + text, + }) + + const stream = new ReadableStream({ + async start(controller) { + for await (const chunk of response) { + controller.enqueue(chunk) + } + controller.close() + }, + }) + + // Branch stream to Supabase Storage + const [browserStream, storageStream] = stream.tee() + + // Upload to Supabase Storage in the background + EdgeRuntime.waitUntil(uploadAudioToStorage(storageStream, requestHash)) + + // Return the streaming response immediately + return new Response(browserStream, { + headers: { + 'Content-Type': 'audio/mpeg', + }, + }) + } catch (error) { + console.log('error', { error }) + return Response.json({ error: error.message }, { status: 500 }) + } + }), } - -Deno.serve(async (req) => { - // To secure your function for production, you can for example validate the request origin, - // or append a user access token and validate it with Supabase Auth. - console.log('Request origin', req.headers.get('host')) - const url = new URL(req.url) - const params = new URLSearchParams(url.search) - const text = params.get('text') - const voiceId = params.get('voiceId') ?? 'JBFqnCBsd6RMkjVDRZzb' - - const requestHash = hash.MD5({ text, voiceId }) - console.log('Request hash', requestHash) - - // Check storage for existing audio file - const { data } = await supabase.storage.from('audio').createSignedUrl(`${requestHash}.mp3`, 60) - - if (data) { - console.log('Audio file found in storage', data) - const storageRes = await fetch(data.signedUrl) - if (storageRes.ok) return storageRes - } - - if (!text) { - return new Response(JSON.stringify({ error: 'Text parameter is required' }), { - status: 400, - headers: { 'Content-Type': 'application/json' }, - }) - } - - try { - console.log('ElevenLabs API call') - const response = await client.textToSpeech.convertAsStream(voiceId, { - output_format: 'mp3_44100_128', - model_id: 'eleven_multilingual_v2', - text, - }) - - const stream = new ReadableStream({ - async start(controller) { - for await (const chunk of response) { - controller.enqueue(chunk) - } - controller.close() - }, - }) - - // Branch stream to Supabase Storage - const [browserStream, storageStream] = stream.tee() - - // Upload to Supabase Storage in the background - EdgeRuntime.waitUntil(uploadAudioToStorage(storageStream, requestHash)) - - // Return the streaming response immediately - return new Response(browserStream, { - headers: { - 'Content-Type': 'audio/mpeg', - }, - }) - } catch (error) { - console.log('error', { error }) - return new Response(JSON.stringify({ error: error.message }), { - status: 500, - headers: { 'Content-Type': 'application/json' }, - }) - } -}) ``` ## Run locally diff --git a/apps/docs/content/guides/functions/examples/elevenlabs-transcribe-speech.mdx b/apps/docs/content/guides/functions/examples/elevenlabs-transcribe-speech.mdx index 6cdc51f58ca..e4913a30afa 100644 --- a/apps/docs/content/guides/functions/examples/elevenlabs-transcribe-speech.mdx +++ b/apps/docs/content/guides/functions/examples/elevenlabs-transcribe-speech.mdx @@ -108,8 +108,11 @@ In your newly created `scribe-bot/index.ts` file, add the following code: ```ts supabase/functions/scribe-bot/index.ts import { Bot, webhookCallback } from 'https://deno.land/x/grammy@v1.34.0/mod.ts' + import 'jsr:@supabase/functions-js/edge-runtime.d.ts' -import { createClient } from 'npm:@supabase/supabase-js@2' + +import { withSupabase } from 'npm:@supabase/server@^1' +import type { SupabaseClient } from 'npm:@supabase/supabase-js@2' import { ElevenLabsClient } from 'npm:elevenlabs@1.50.5' console.log(`Function "elevenlabs-scribe-bot" up and running!`) @@ -117,13 +120,9 @@ console.log(`Function "elevenlabs-scribe-bot" up and running!`) const elevenLabsClient = new ElevenLabsClient({ apiKey: Deno.env.get('ELEVENLABS_API_KEY') || '', }) -const SUPABASE_SECRET_KEYS = JSON.parse(Deno.env.get('SUPABASE_SECRET_KEYS')!) -const supabase = createClient( - Deno.env.get('SUPABASE_URL') || '', - SUPABASE_SECRET_KEYS['default'] || '' -) async function scribe({ + supabaseAdmin, fileURL, fileType, duration, @@ -131,6 +130,7 @@ async function scribe({ messageId, username, }: { + supabaseAdmin: SupabaseClient fileURL: string fileType: string duration: number @@ -178,9 +178,13 @@ async function scribe({ error: errorMsg, } console.log({ logLine }) - await supabase.from('transcription_logs').insert({ ...logLine, transcript }) + await supabaseAdmin.from('transcription_logs').insert({ ...logLine, transcript }) } +// Set by the request handler before delegating to grammY, so bot handlers +// can write transcription logs with the admin client. +let supabaseAdmin: SupabaseClient + const telegramBotToken = Deno.env.get('TELEGRAM_BOT_TOKEN') const bot = new Bot(telegramBotToken || '') const startMessage = `Welcome to the ElevenLabs Scribe Bot\\! I can transcribe speech in 99 languages with super high accuracy\\! @@ -202,6 +206,7 @@ bot.on([':voice', ':audio', ':video'], async (ctx) => { // Run the transcription in the background. EdgeRuntime.waitUntil( scribe({ + supabaseAdmin, fileURL, fileType: fileMeta.mime_type!, duration: fileMeta.duration, @@ -223,18 +228,24 @@ bot.on([':voice', ':audio', ':video'], async (ctx) => { const handleUpdate = webhookCallback(bot, 'std/http') -Deno.serve(async (req) => { - try { - const url = new URL(req.url) - if (url.searchParams.get('secret') !== Deno.env.get('FUNCTION_SECRET')) { - return new Response('not allowed', { status: 405 }) - } +// Deploy with verify_jwt = false +// The bot is called by Telegram, so we verify the request with FUNCTION_SECRET in code. +export default { + fetch: withSupabase({ auth: 'none' }, async (req, ctx) => { + try { + const url = new URL(req.url) + if (url.searchParams.get('secret') !== Deno.env.get('FUNCTION_SECRET')) { + return new Response('not allowed', { status: 405 }) + } - return await handleUpdate(req) - } catch (err) { - console.error(err) - } -}) + supabaseAdmin = ctx.supabaseAdmin + + return await handleUpdate(req) + } catch (err) { + console.error(err) + } + }), +} ``` ## Deploy to Supabase diff --git a/apps/docs/content/guides/functions/examples/og-image.mdx b/apps/docs/content/guides/functions/examples/og-image.mdx index ec076c16b7c..71cef4ad1ee 100644 --- a/apps/docs/content/guides/functions/examples/og-image.mdx +++ b/apps/docs/content/guides/functions/examples/og-image.mdx @@ -21,8 +21,8 @@ Generate Open Graph images with Deno and Supabase Edge Functions. [View on GitHu Create a `handler.tsx` file to construct the OG image in React: ```tsx handler.tsx -import React from 'https://esm.sh/react@18.2.0' import { ImageResponse } from 'https://deno.land/x/og_edge@0.0.4/mod.ts' +import React from 'https://esm.sh/react@18.2.0' export default function handler(req: Request) { return new ImageResponse( @@ -46,9 +46,12 @@ export default function handler(req: Request) { Create an `index.ts` file to execute the handler on incoming requests: ```ts index.ts +import { withSupabase } from 'npm:@supabase/server@^1' + import handler from './handler.tsx' console.log('Hello from og-image Function!') -Deno.serve(handler) +// Public image endpoint, so deploy with --no-verify-jwt. +export default { fetch: withSupabase({ auth: 'none' }, handler) } ``` diff --git a/apps/docs/content/guides/functions/examples/push-notifications.mdx b/apps/docs/content/guides/functions/examples/push-notifications.mdx index d36d99ef201..b346ebe70b7 100644 --- a/apps/docs/content/guides/functions/examples/push-notifications.mdx +++ b/apps/docs/content/guides/functions/examples/push-notifications.mdx @@ -53,7 +53,7 @@ Push notifications are an important part of any mobile app. They allow you to se 1. `supabase secrets set --env-file .env.local` ```ts supabase/functions/push/index.ts - import { createClient } from 'npm:@supabase/supabase-js@2' + import { withSupabase } from 'npm:@supabase/server@^1' console.log('Hello from Functions!') @@ -71,39 +71,33 @@ Push notifications are an important part of any mobile app. They allow you to se old_record: null | Notification } - const SUPABASE_SECRET_KEYS = JSON.parse(Deno.env.get('SUPABASE_SECRET_KEYS')!) + // Triggered by a Database Webhook, which authenticates with a secret key. + // Deploy with `verify_jwt = false`. + export default { + fetch: withSupabase({ auth: 'secret' }, async (req, ctx) => { + const payload: WebhookPayload = await req.json() + const { data } = await ctx.supabaseAdmin + .from('profiles') + .select('expo_push_token') + .eq('id', payload.record.user_id) + .single() - // If you want to use a different api key, change 'default' to your preferred key name - const supabase = createClient( - Deno.env.get('SUPABASE_URL')!, - SUPABASE_SECRET_KEYS['default'] - ) + const res = await fetch('https://exp.host/--/api/v2/push/send', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${Deno.env.get('EXPO_ACCESS_TOKEN')}`, + }, + body: JSON.stringify({ + to: data?.expo_push_token, + sound: 'default', + body: payload.record.body, + }), + }).then((res) => res.json()) - Deno.serve(async (req) => { - const payload: WebhookPayload = await req.json() - const { data } = await supabase - .from('profiles') - .select('expo_push_token') - .eq('id', payload.record.user_id) - .single() - - const res = await fetch('https://exp.host/--/api/v2/push/send', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${Deno.env.get('EXPO_ACCESS_TOKEN')}`, - }, - body: JSON.stringify({ - to: data?.expo_push_token, - sound: 'default', - body: payload.record.body, - }), - }).then((res) => res.json()) - - return new Response(JSON.stringify(res), { - headers: { 'Content-Type': 'application/json' }, - }) - }) + return Response.json(res) + }), + } ``` ## Create the database webhook @@ -169,7 +163,7 @@ Push notifications are an important part of any mobile app. They allow you to se Add the following code to `supabase/functions/push/index.ts`: ```ts supabase/functions/push/index.ts - import { createClient } from 'npm:@supabase/supabase-js@2' + import { withSupabase } from 'npm:@supabase/server@^1' import { JWT } from 'npm:google-auth-library@9' import serviceAccount from '../service-account.json' with { type: 'json' } @@ -186,59 +180,53 @@ Push notifications are an important part of any mobile app. They allow you to se schema: 'public' } - const SUPABASE_SECRET_KEYS = JSON.parse(Deno.env.get('SUPABASE_SECRET_KEYS')!) + // Triggered by a Database Webhook, which authenticates with a secret key. + // Deploy with `verify_jwt = false`. + export default { + fetch: withSupabase({ auth: 'secret' }, async (req, ctx) => { + const payload: WebhookPayload = await req.json() - // If you want to use a different api key, change 'default' to your preferred key name - const supabase = createClient( - Deno.env.get('SUPABASE_URL')!, - SUPABASE_SECRET_KEYS['default'] - ) + const { data } = await ctx.supabaseAdmin + .from('profiles') + .select('fcm_token') + .eq('id', payload.record.user_id) + .single() - Deno.serve(async (req) => { - const payload: WebhookPayload = await req.json() + const fcmToken = data!.fcm_token as string - const { data } = await supabase - .from('profiles') - .select('fcm_token') - .eq('id', payload.record.user_id) - .single() + const accessToken = await getAccessToken({ + clientEmail: serviceAccount.client_email, + privateKey: serviceAccount.private_key, + }) - const fcmToken = data!.fcm_token as string - - const accessToken = await getAccessToken({ - clientEmail: serviceAccount.client_email, - privateKey: serviceAccount.private_key, - }) - - const res = await fetch( - `https://fcm.googleapis.com/v1/projects/${serviceAccount.project_id}/messages:send`, - { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${accessToken}`, - }, - body: JSON.stringify({ - message: { - token: fcmToken, - notification: { - title: `Notification from Supabase`, - body: payload.record.body, - }, + const res = await fetch( + `https://fcm.googleapis.com/v1/projects/${serviceAccount.project_id}/messages:send`, + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${accessToken}`, }, - }), + body: JSON.stringify({ + message: { + token: fcmToken, + notification: { + title: `Notification from Supabase`, + body: payload.record.body, + }, + }, + }), + } + ) + + const resData = await res.json() + if (res.status < 200 || 299 < res.status) { + throw resData } - ) - const resData = await res.json() - if (res.status < 200 || 299 < res.status) { - throw resData - } - - return new Response(JSON.stringify(resData), { - headers: { 'Content-Type': 'application/json' }, - }) - }) + return Response.json(resData) + }), + } const getAccessToken = ({ clientEmail, diff --git a/apps/docs/content/guides/functions/examples/semantic-search.mdx b/apps/docs/content/guides/functions/examples/semantic-search.mdx index db717653b6c..47548c35d7d 100644 --- a/apps/docs/content/guides/functions/examples/semantic-search.mdx +++ b/apps/docs/content/guides/functions/examples/semantic-search.mdx @@ -37,28 +37,34 @@ create index on embeddings using hnsw (embedding vector_ip_ops); You can deploy the [following edge function](https://github.com/supabase/supabase/blob/master/examples/ai/edge-functions/supabase/functions/generate-embedding/index.ts) as a [database webhook](/docs/guides/database/webhooks) to generate the embeddings for any text content inserted into the table: -```tsx +```ts +import { withSupabase } from 'npm:@supabase/server@^1' + const model = new Supabase.ai.Session('gte-small') -Deno.serve(async (req) => { - const payload: WebhookPayload = await req.json() - const { content, id } = payload.record +// Triggered by a Database Webhook, which authenticates with a secret key. +// Deploy with `verify_jwt = false`. +export default { + fetch: withSupabase({ auth: 'secret' }, async (req, ctx) => { + const payload: WebhookPayload = await req.json() + const { content, id } = payload.record - // Generate embedding. - const embedding = await model.run(content, { - mean_pool: true, - normalize: true, - }) + // Generate embedding. + const embedding = await model.run(content, { + mean_pool: true, + normalize: true, + }) - // Store in database. - const { error } = await supabase - .from('embeddings') - .update({ embedding: JSON.stringify(embedding) }) - .eq('id', id) - if (error) console.warn(error.message) + // Store in database. + const { error } = await ctx.supabaseAdmin + .from('embeddings') + .update({ embedding: JSON.stringify(embedding) }) + .eq('id', id) + if (error) console.warn(error.message) - return new Response('ok') -}) + return new Response('ok') + }), +} ``` ## Create a Database Function and RPC @@ -98,32 +104,36 @@ $$; You can use `supabase-js` to first generate the embedding for the search term and then invoke the Postgres function to find the relevant results from your stored embeddings, right from your [Supabase Edge Function](https://github.com/supabase/supabase/blob/master/examples/ai/edge-functions/supabase/functions/search/index.ts): -```tsx +```ts +import { withSupabase } from 'npm:@supabase/server@^1' + const model = new Supabase.ai.Session('gte-small') -Deno.serve(async (req) => { - const { search } = await req.json() - if (!search) return new Response('Please provide a search param!') - // Generate embedding for search term. - const embedding = await model.run(search, { - mean_pool: true, - normalize: true, - }) - - // Query embeddings. - const { data: result, error } = await supabase - .rpc('query_embeddings', { - embedding, - match_threshold: 0.8, +export default { + fetch: withSupabase({ auth: 'user' }, async (req, ctx) => { + const { search } = await req.json() + if (!search) return new Response('Please provide a search param!') + // Generate embedding for search term. + const embedding = await model.run(search, { + mean_pool: true, + normalize: true, }) - .select('content') - .limit(3) - if (error) { - return Response.json(error) - } - return Response.json({ search, result }) -}) + // Query embeddings. + const { data: result, error } = await ctx.supabase + .rpc('query_embeddings', { + embedding, + match_threshold: 0.8, + }) + .select('content') + .limit(3) + if (error) { + return Response.json(error) + } + + return Response.json({ search, result }) + }), +} ``` You now have AI powered semantic search set up without any external dependencies! Just you, pgvector, and Supabase Edge Functions! diff --git a/apps/docs/content/guides/functions/examples/send-emails.mdx b/apps/docs/content/guides/functions/examples/send-emails.mdx index 60fc7926ad5..c9bcef0f723 100644 --- a/apps/docs/content/guides/functions/examples/send-emails.mdx +++ b/apps/docs/content/guides/functions/examples/send-emails.mdx @@ -30,6 +30,8 @@ Store the `RESEND_API_KEY` in your `.env` file. Paste the following code into the `index.ts` file: ```tsx +import { withSupabase } from 'npm:@supabase/server@^1' + const RESEND_API_KEY = Deno.env.get('RESEND_API_KEY') const handler = async (_request: Request): Promise => { @@ -49,15 +51,10 @@ const handler = async (_request: Request): Promise => { const data = await res.json() - return new Response(JSON.stringify(data), { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - }) + return Response.json(data) } -Deno.serve(handler) +export default { fetch: withSupabase({ auth: ['user', 'secret'] }, handler) } ``` ### 3. Deploy and send email @@ -69,7 +66,12 @@ supabase start supabase functions serve --no-verify-jwt --env-file .env ``` -Test it: http://localhost:54321/functions/v1/resend +The function accepts a signed-in user's JWT or a secret key, so it can be triggered from your app (via `supabase.functions.invoke`) or from a database function. Test it locally with a secret key: + +```bash +curl -i --request POST 'http://localhost:54321/functions/v1/resend' \ + --header 'apikey: ' +``` Deploy function to Supabase: @@ -83,8 +85,6 @@ When you deploy to Supabase, make sure that your `RESEND_API_KEY` is set in [Edg -Open the endpoint URL to send an email: - ### 4. Try it yourself Find the complete example on [GitHub](https://github.com/resendlabs/resend-supabase-edge-functions-example). diff --git a/apps/docs/content/guides/functions/examples/sentry-monitoring.mdx b/apps/docs/content/guides/functions/examples/sentry-monitoring.mdx index ae6d901ebae..9a691e28233 100644 --- a/apps/docs/content/guides/functions/examples/sentry-monitoring.mdx +++ b/apps/docs/content/guides/functions/examples/sentry-monitoring.mdx @@ -24,6 +24,7 @@ Handle exceptions within your function and send them to Sentry. ```tsx import * as Sentry from 'https://deno.land/x/sentry/index.mjs' +import { withSupabase } from 'npm:@supabase/server@^1' Sentry.init({ // https://docs.sentry.io/product/sentry-basics/concepts/dsn-explainer/#where-to-find-your-dsn @@ -39,25 +40,25 @@ Sentry.init({ Sentry.setTag('region', Deno.env.get('SB_REGION')) Sentry.setTag('execution_id', Deno.env.get('SB_EXECUTION_ID')) -Deno.serve(async (req) => { - try { - const { name } = await req.json() - // This will throw, as `name` in our example call will be `undefined` - const data = { - message: `Hello ${name}!`, - } +// Open endpoint for testing. In production, implement an authorization layer in the handler or switch the auth mode. +export default { + fetch: withSupabase({ auth: 'none' }, async (req, ctx) => { + try { + const { name } = await req.json() + // This will throw, as `name` in our example call will be `undefined` + const data = { + message: `Hello ${name}!`, + } - return new Response(JSON.stringify(data), { headers: { 'Content-Type': 'application/json' } }) - } catch (e) { - Sentry.captureException(e) - // Flush Sentry before the running process closes - await Sentry.flush(2000) - return new Response(JSON.stringify({ msg: 'error' }), { - status: 500, - headers: { 'Content-Type': 'application/json' }, - }) - } -}) + return Response.json(data) + } catch (e) { + Sentry.captureException(e) + // Flush Sentry before the running process closes + await Sentry.flush(2000) + return Response.json({ msg: 'error' }, { status: 500 }) + } + }), +} ``` ### 3. Deploy and test diff --git a/apps/docs/content/guides/functions/examples/slack-bot-mention.mdx b/apps/docs/content/guides/functions/examples/slack-bot-mention.mdx index 63aed481548..9f78d84aedd 100644 --- a/apps/docs/content/guides/functions/examples/slack-bot-mention.mdx +++ b/apps/docs/content/guides/functions/examples/slack-bot-mention.mdx @@ -28,37 +28,38 @@ Here's the code of the Edge Function, you can change the response to handle the ```ts index.ts import { WebClient } from 'https://deno.land/x/slack_web_api@6.7.2/mod.js' +import { withSupabase } from 'npm:@supabase/server@^1' const slackBotToken = Deno.env.get('SLACK_TOKEN') ?? '' const botClient = new WebClient(slackBotToken) console.log(`Slack URL verification function up and running!`) -Deno.serve(async (req) => { - try { - const reqBody = await req.json() - console.log(JSON.stringify(reqBody, null, 2)) - const { token, challenge, type, event } = reqBody - if (type == 'url_verification') { - return new Response(JSON.stringify({ challenge }), { - headers: { 'Content-Type': 'application/json' }, - status: 200, - }) - } else if (event.type == 'app_mention') { - const { user, text, channel, ts } = event - // Here you should process the text received and return a response: - const response = await botClient.chat.postMessage({ - channel: channel, - text: `Hello <@${user}>!`, - thread_ts: ts, - }) - return new Response('ok', { status: 200 }) +// Slack calls this endpoint, so deploy with --no-verify-jwt. +export default { + fetch: withSupabase({ auth: 'none' }, async (req) => { + try { + // Implement your Slack request signature verification here before trusting the payload + // (validate `x-slack-signature` / `x-slack-request-timestamp` with your signing secret). + const reqBody = await req.json() + console.log(JSON.stringify(reqBody, null, 2)) + const { token, challenge, type, event } = reqBody + + if (type == 'url_verification') { + return Response.json({ challenge }) + } else if (event.type == 'app_mention') { + const { user, text, channel, ts } = event + // Here you should process the text received and return a response: + const response = await botClient.chat.postMessage({ + channel: channel, + text: `Hello <@${user}>!`, + thread_ts: ts, + }) + return new Response('ok', { status: 200 }) + } + } catch (error) { + return Response.json({ error: error.message }, { status: 500 }) } - } catch (error) { - return new Response(JSON.stringify({ error: error.message }), { - headers: { 'Content-Type': 'application/json' }, - status: 500, - }) - } -}) + }), +} ``` diff --git a/apps/docs/content/guides/functions/examples/upstash-redis.mdx b/apps/docs/content/guides/functions/examples/upstash-redis.mdx index 5fdd926f830..630de49aca5 100644 --- a/apps/docs/content/guides/functions/examples/upstash-redis.mdx +++ b/apps/docs/content/guides/functions/examples/upstash-redis.mdx @@ -40,39 +40,43 @@ And add the code to the `index.ts` file: ```ts index.ts import { Redis } from 'https://deno.land/x/upstash_redis@v1.19.3/mod.ts' +import { withSupabase } from 'npm:@supabase/server@^1' console.log(`Function "upstash-redis-counter" up and running!`) -Deno.serve(async (_req) => { - try { - const redis = new Redis({ - url: Deno.env.get('UPSTASH_REDIS_REST_URL')!, - token: Deno.env.get('UPSTASH_REDIS_REST_TOKEN')!, - }) - - const deno_region = Deno.env.get('DENO_REGION') - if (deno_region) { - // Increment region counter - await redis.hincrby('supa-edge-counter', deno_region, 1) - } else { - // Increment localhost counter - await redis.hincrby('supa-edge-counter', 'localhost', 1) - } - - // Get all values - const counterHash: Record | null = await redis.hgetall('supa-edge-counter') - const counters = Object.entries(counterHash!) - .sort(([, a], [, b]) => b - a) // sort desc - .reduce((r, [k, v]) => ({ total: r.total + v, regions: { ...r.regions, [k]: v } }), { - total: 0, - regions: {}, +// Open endpoint for testing. In production, implement an authorization layer in the handler or switch the auth mode. +export default { + fetch: withSupabase({ auth: 'none' }, async (req, ctx) => { + try { + const redis = new Redis({ + url: Deno.env.get('UPSTASH_REDIS_REST_URL')!, + token: Deno.env.get('UPSTASH_REDIS_REST_TOKEN')!, }) - return new Response(JSON.stringify({ counters }), { status: 200 }) - } catch (error) { - return new Response(JSON.stringify({ error: error.message }), { status: 200 }) - } -}) + const deno_region = Deno.env.get('DENO_REGION') + if (deno_region) { + // Increment region counter + await redis.hincrby('supa-edge-counter', deno_region, 1) + } else { + // Increment localhost counter + await redis.hincrby('supa-edge-counter', 'localhost', 1) + } + + // Get all values + const counterHash: Record | null = await redis.hgetall('supa-edge-counter') + const counters = Object.entries(counterHash!) + .sort(([, a], [, b]) => b - a) // sort desc + .reduce((r, [k, v]) => ({ total: r.total + v, regions: { ...r.regions, [k]: v } }), { + total: 0, + regions: {}, + }) + + return Response.json({ counters }) + } catch (error) { + return Response.json({ error: error.message }, { status: 500 }) + } + }), +} ``` ## Run locally diff --git a/apps/docs/content/guides/functions/kysely-postgres.mdx b/apps/docs/content/guides/functions/kysely-postgres.mdx index a8930899f96..0d61b084322 100644 --- a/apps/docs/content/guides/functions/kysely-postgres.mdx +++ b/apps/docs/content/guides/functions/kysely-postgres.mdx @@ -198,6 +198,7 @@ import { PostgresIntrospector, PostgresQueryCompiler, } from 'https://esm.sh/kysely@0.23.4' +import { withSupabase } from 'npm:@supabase/server@^1' import { PostgresDriver } from './DenoPostgresDriver.ts' @@ -245,31 +246,36 @@ const db = new Kysely({ }, }) -Deno.serve(async (_req) => { - try { - // Run a query - const animals = await db.selectFrom('animals').select(['id', 'animal', 'created_at']).execute() +export default { + fetch: withSupabase({ auth: 'user' }, async (_req, ctx) => { + try { + // Run a query + const animals = await db + .selectFrom('animals') + .select(['id', 'animal', 'created_at']) + .execute() - // Neat, it's properly typed \o/ - console.log(animals[0].created_at.getFullYear()) + // Neat, it's properly typed \o/ + console.log(animals[0].created_at.getFullYear()) - // Encode the result as pretty printed JSON - const body = JSON.stringify( - animals, - (key, value) => (typeof value === 'bigint' ? value.toString() : value), - 2 - ) + // Encode the result as pretty printed JSON + const body = JSON.stringify( + animals, + (key, value) => (typeof value === 'bigint' ? value.toString() : value), + 2 + ) - // Return the response with the correct content type header - return new Response(body, { - status: 200, - headers: { - 'Content-Type': 'application/json; charset=utf-8', - }, - }) - } catch (err) { - console.error(err) - return new Response(String(err?.message ?? err), { status: 500 }) - } -}) + // Return the response with the correct content type header + return new Response(body, { + status: 200, + headers: { + 'Content-Type': 'application/json; charset=utf-8', + }, + }) + } catch (err) { + console.error(err) + return new Response(String(err?.message ?? err), { status: 500 }) + } + }), +} ``` diff --git a/apps/docs/content/guides/functions/routing.mdx b/apps/docs/content/guides/functions/routing.mdx index 89e785455e5..3e112ee2d20 100644 --- a/apps/docs/content/guides/functions/routing.mdx +++ b/apps/docs/content/guides/functions/routing.mdx @@ -39,16 +39,20 @@ Here's a simple hello world example using some popular web frameworks: ```ts -Deno.serve(async (req) => { - if (req.method === 'GET') { +import { withSupabase } from 'npm:@supabase/server@^1' + +export default { + fetch: withSupabase({ auth: 'user' }, async (req, ctx) => { + if (req.method === 'GET') { + return new Response('Hello World!') + } + const { name } = await req.json() + if (name) { + return new Response(`Hello ${name}!`) + } return new Response('Hello World!') - } - const { name } = await req.json() - if (name) { - return new Response(`Hello ${name}!`) - } - return new Response('Hello World!') -}) + }), +} ``` @@ -123,9 +127,11 @@ app.get('/hello-world', (c) => { return new Response('Hello World!') }) -Deno.serve(app.fetch) +export default { fetch: app.fetch } ``` +To add Supabase auth per route, use the Hono adapter from `npm:@supabase/server@^1/adapters/hono`. See [Securing Edge Functions](/docs/guides/functions/auth). + @@ -155,6 +161,8 @@ Keep in mind paths must be prefixed by function name. Route parameters can only ```ts +import { withSupabase } from 'npm:@supabase/server@^1' + interface Task { id: string name: string @@ -204,42 +212,44 @@ async function deleteTask(id: string): Promise { } } -Deno.serve(async (req) => { - const url = new URL(req.url) - const method = req.method - // Extract the last part of the path as the command - const command = url.pathname.split('/').pop() - // Assuming the last part of the path is the task ID - const id = command - try { - switch (method) { - case 'GET': - if (id) { - return getTask(id) - } else { - return getAllTasks() - } - case 'POST': - return createTask(req) - case 'PUT': - if (id) { - return updateTask(id, req) - } else { - return new Response('Bad Request', { status: 400 }) - } - case 'DELETE': - if (id) { - return deleteTask(id) - } else { - return new Response('Bad Request', { status: 400 }) - } - default: - return new Response('Method Not Allowed', { status: 405 }) +export default { + fetch: withSupabase({ auth: 'user' }, async (req, ctx) => { + const url = new URL(req.url) + const method = req.method + // Extract the last part of the path as the command + const command = url.pathname.split('/').pop() + // Assuming the last part of the path is the task ID + const id = command + try { + switch (method) { + case 'GET': + if (id) { + return getTask(id) + } else { + return getAllTasks() + } + case 'POST': + return createTask(req) + case 'PUT': + if (id) { + return updateTask(id, req) + } else { + return new Response('Bad Request', { status: 400 }) + } + case 'DELETE': + if (id) { + return deleteTask(id) + } else { + return new Response('Bad Request', { status: 400 }) + } + default: + return new Response('Method Not Allowed', { status: 405 }) + } + } catch (error) { + return new Response(`Internal Server Error: ${error}`, { status: 500 }) } - } catch (error) { - return new Response(`Internal Server Error: ${error}`, { status: 500 }) - } -}) + }), +} ``` @@ -388,9 +398,11 @@ app.delete('/:id', async (c) => { } }) -Deno.serve(app.fetch) +export default { fetch: app.fetch } ``` +To add Supabase auth per route, use the Hono adapter from `npm:@supabase/server@^1/adapters/hono`. See [Securing Edge Functions](/docs/guides/functions/auth). + @@ -407,6 +419,6 @@ This works well for small apps with only a couple of routes: <$CodeSample path="/edge-functions/supabase/functions/restful-tasks/index.ts" -lines={[[92, 116]]} +lines={[[48, -1]]} meta="restful-tasks/index.ts" /> diff --git a/apps/docs/content/guides/functions/websockets.mdx b/apps/docs/content/guides/functions/websockets.mdx index 05ce306d4df..8129b4e2af6 100644 --- a/apps/docs/content/guides/functions/websockets.mdx +++ b/apps/docs/content/guides/functions/websockets.mdx @@ -31,26 +31,28 @@ Here are some basic examples of setting up WebSocket servers using Deno and Node ```ts -Deno.serve((req) => { - const upgrade = req.headers.get('upgrade') || '' +export default { + fetch: (req) => { + const upgrade = req.headers.get('upgrade') || '' - if (upgrade.toLowerCase() != 'websocket') { - return new Response("request isn't trying to upgrade to WebSocket.", { status: 400 }) - } + if (upgrade.toLowerCase() != 'websocket') { + return new Response("request isn't trying to upgrade to WebSocket.", { status: 400 }) + } - const { socket, response } = Deno.upgradeWebSocket(req) + const { socket, response } = Deno.upgradeWebSocket(req) - socket.onopen = () => console.log('socket opened') - socket.onmessage = (e) => { - console.log('socket message:', e.data) - socket.send(new Date().toString()) - } + socket.onopen = () => console.log('socket opened') + socket.onmessage = (e) => { + console.log('socket message:', e.data) + socket.send(new Date().toString()) + } - socket.onerror = (e) => console.log('socket errored:', e.message) - socket.onclose = () => console.log('socket closed') + socket.onerror = (e) => console.log('socket errored:', e.message) + socket.onclose = () => console.log('socket closed') - return response -}) + return response + }, +} ``` @@ -123,7 +125,7 @@ WebSocket browser clients don't have the option to send custom headers. Because You can skip the default authorization header checks by explicitly providing `--no-verify-jwt` when serving and deploying functions. -To authenticate the user making WebSocket requests, you can pass the JWT in URL query params or via a custom protocol. +To authenticate the user making WebSocket requests, you can pass the JWT in URL query params or via a custom protocol. The [`withSupabase`](/docs/guides/functions/auth) wrapper validates credentials on request headers, so it can't authenticate WebSocket clients. Verify the JWT yourself, as shown below. { - const upgrade = req.headers.get('upgrade') || '' - if (upgrade.toLowerCase() != 'WebSocket') { - return new Response("request isn't trying to upgrade to WebSocket.", { status: 400 }) - } +export default { + fetch: async (req) => { + const upgrade = req.headers.get('upgrade') || '' + if (upgrade.toLowerCase() != 'websocket') { + return new Response("request isn't trying to upgrade to WebSocket.", { status: 400 }) + } - // Please be aware query params may be logged in some logging systems. - const url = new URL(req.url) - const jwt = url.searchParams.get('jwt') + // Please be aware query params may be logged in some logging systems. + const url = new URL(req.url) + const jwt = url.searchParams.get('jwt') - if (!jwt) { - console.error('Auth token not provided') - return new Response('Auth token not provided', { status: 403 }) - } + if (!jwt) { + console.error('Auth token not provided') + return new Response('Auth token not provided', { status: 403 }) + } - const { error, data } = await supabase.auth.getClaims() + const { error, data } = await supabase.auth.getUser(jwt) - if (error) { - console.error(error) - return new Response('Invalid token provided', { status: 403 }) - } + if (error) { + console.error(error) + return new Response('Invalid token provided', { status: 403 }) + } - if (!data.user) { - console.error('user is not authenticated') - return new Response('User is not authenticated', { status: 403 }) - } + if (!data.user) { + console.error('user is not authenticated') + return new Response('User is not authenticated', { status: 403 }) + } - const { socket, response } = Deno.upgradeWebSocket(req) + const { socket, response } = Deno.upgradeWebSocket(req) - socket.onopen = () => console.log('socket opened') - socket.onmessage = (e) => { - console.log('socket message:', e.data) - socket.send(new Date().toString()) - } + socket.onopen = () => console.log('socket opened') + socket.onmessage = (e) => { + console.log('socket message:', e.data) + socket.send(new Date().toString()) + } - socket.onerror = (e) => console.log('socket errored:', e.message) - socket.onclose = () => console.log('socket closed') + socket.onerror = (e) => console.log('socket errored:', e.message) + socket.onclose = () => console.log('socket closed') - return response -}) + return response + }, +} ``` @@ -199,47 +203,50 @@ const supabase = createClient( SUPABASE_SECRET_KEYS['default'] ) -Deno.serve((req) => { - const upgrade = req.headers.get('upgrade') || '' - if (upgrade.toLowerCase() != 'WebSocket') { - return new Response("request isn't trying to upgrade to WebSocket.", { status: 400 }) - } +export default { + fetch: async (req) => { + const upgrade = req.headers.get('upgrade') || '' + if (upgrade.toLowerCase() != 'websocket') { + return new Response("request isn't trying to upgrade to WebSocket.", { status: 400 }) + } - // Sec-WebScoket-Protocol may return multiple protocol values `jwt-TOKEN, value1, value 2` - const customProtocols = (req.headers.get('Sec-WebSocket-Protocol') ?? '') - .split(',') - .map((p) => p.trim()) - const jwt = customProtocols.find((p) => p.startsWith('jwt')).replace('jwt-', '') + // Sec-WebScoket-Protocol may return multiple protocol values `jwt-TOKEN, value1, value 2` + const customProtocols = (req.headers.get('Sec-WebSocket-Protocol') ?? '') + .split(',') + .map((p) => p.trim()) + const jwtProtocol = customProtocols.find((p) => p.startsWith('jwt-')) + const jwt = jwtProtocol ? jwtProtocol.replace('jwt-', '') : null - if (!jwt) { - console.error('Auth token not provided') - return new Response('Auth token not provided', { status: 403 }) - } + if (!jwt) { + console.error('Auth token not provided') + return new Response('Auth token not provided', { status: 403 }) + } - const { error, data } = await supabase.auth.getClaims() - if (error) { - console.error(error) - return new Response('Invalid token provided', { status: 403 }) - } + const { error, data } = await supabase.auth.getUser(jwt) + if (error) { + console.error(error) + return new Response('Invalid token provided', { status: 403 }) + } - if (!data.user) { - console.error('user is not authenticated') - return new Response('User is not authenticated', { status: 403 }) - } + if (!data.user) { + console.error('user is not authenticated') + return new Response('User is not authenticated', { status: 403 }) + } - const { socket, response } = Deno.upgradeWebSocket(req) + const { socket, response } = Deno.upgradeWebSocket(req) - socket.onopen = () => console.log('socket opened') - socket.onmessage = (e) => { - console.log('socket message:', e.data) - socket.send(new Date().toString()) - } + socket.onopen = () => console.log('socket opened') + socket.onmessage = (e) => { + console.log('socket message:', e.data) + socket.send(new Date().toString()) + } - socket.onerror = (e) => console.log('socket errored:', e.message) - socket.onclose = () => console.log('socket closed') + socket.onerror = (e) => console.log('socket errored:', e.message) + socket.onclose = () => console.log('socket closed') - return response -}) + return response + }, +} ``` diff --git a/examples/edge-functions/supabase/functions/drizzle/index.ts b/examples/edge-functions/supabase/functions/drizzle/index.ts index fede266f225..426347072b0 100644 --- a/examples/edge-functions/supabase/functions/drizzle/index.ts +++ b/examples/edge-functions/supabase/functions/drizzle/index.ts @@ -1,5 +1,6 @@ import { drizzle } from 'drizzle-orm/postgres-js' import postgres from 'postgres' + import { countries } from '../_shared/schema.ts' const connectionString = Deno.env.get('SUPABASE_DB_URL')! @@ -7,8 +8,10 @@ const connectionString = Deno.env.get('SUPABASE_DB_URL')! const client = postgres(connectionString, { prepare: false }) const db = drizzle(client) -Deno.serve(async (_req) => { - const allCountries = await db.select().from(countries) +export default { + fetch: async (_req) => { + const allCountries = await db.select().from(countries) - return Response.json(allCountries) -}) + return Response.json(allCountries) + }, +} diff --git a/examples/edge-functions/supabase/functions/postgres-on-the-edge/index.ts b/examples/edge-functions/supabase/functions/postgres-on-the-edge/index.ts index f8883ce3fb0..d3d51f0b2e9 100644 --- a/examples/edge-functions/supabase/functions/postgres-on-the-edge/index.ts +++ b/examples/edge-functions/supabase/functions/postgres-on-the-edge/index.ts @@ -13,36 +13,38 @@ const pool = new Pool( 1 ) -Deno.serve(async (_req) => { - try { - // Grab a connection from the pool - const connection = await pool.connect() - +export default { + fetch: async (_req) => { try { - // Run a query - const result = await connection.queryObject`SELECT * FROM animals` - const animals = result.rows // [{ id: 1, name: "Lion" }, ...] + // Grab a connection from the pool + const connection = await pool.connect() - // Encode the result as pretty printed JSON - const body = JSON.stringify( - animals, - (_key, value) => (typeof value === 'bigint' ? value.toString() : value), - 2 - ) + try { + // Run a query + const result = await connection.queryObject`SELECT * FROM animals` + const animals = result.rows // [{ id: 1, name: "Lion" }, ...] - // Return the response with the correct content type header - return new Response(body, { - status: 200, - headers: { - 'Content-Type': 'application/json; charset=utf-8', - }, - }) - } finally { - // Release the connection back into the pool - connection.release() + // Encode the result as pretty printed JSON + const body = JSON.stringify( + animals, + (_key, value) => (typeof value === 'bigint' ? value.toString() : value), + 2 + ) + + // Return the response with the correct content type header + return new Response(body, { + status: 200, + headers: { + 'Content-Type': 'application/json; charset=utf-8', + }, + }) + } finally { + // Release the connection back into the pool + connection.release() + } + } catch (err) { + console.error(err) + return new Response(String(err?.message ?? err), { status: 500 }) } - } catch (err) { - console.error(err) - return new Response(String(err?.message ?? err), { status: 500 }) - } -}) + }, +} diff --git a/examples/edge-functions/supabase/functions/restful-tasks/index.ts b/examples/edge-functions/supabase/functions/restful-tasks/index.ts index 0b4527abde8..fac385bf65d 100644 --- a/examples/edge-functions/supabase/functions/restful-tasks/index.ts +++ b/examples/edge-functions/supabase/functions/restful-tasks/index.ts @@ -2,15 +2,8 @@ // https://deno.land/manual/getting_started/setup_your_environment // This enables autocomplete, go to definition, etc. -import { createClient, SupabaseClient } from 'npm:supabase-js@2' -// New approach (v2.95.0+) -import { corsHeaders } from 'jsr:@supabase/supabase-js@2/cors' -// For older versions, use hardcoded headers: -// const corsHeaders = { -// 'Access-Control-Allow-Origin': '*', -// 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type', -// 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT, DELETE', -// } +import { withSupabase } from 'npm:@supabase/server@^1' +import type { SupabaseClient } from 'npm:@supabase/supabase-js@2' interface Task { name: string @@ -21,109 +14,76 @@ async function getTask(supabaseClient: SupabaseClient, id: string) { const { data: task, error } = await supabaseClient.from('tasks').select('*').eq('id', id) if (error) throw error - return new Response(JSON.stringify({ task }), { - headers: { ...corsHeaders, 'Content-Type': 'application/json' }, - status: 200, - }) + return Response.json({ task }) } async function getAllTasks(supabaseClient: SupabaseClient) { const { data: tasks, error } = await supabaseClient.from('tasks').select('*') if (error) throw error - return new Response(JSON.stringify({ tasks }), { - headers: { ...corsHeaders, 'Content-Type': 'application/json' }, - status: 200, - }) + return Response.json({ tasks }) } async function deleteTask(supabaseClient: SupabaseClient, id: string) { const { error } = await supabaseClient.from('tasks').delete().eq('id', id) if (error) throw error - return new Response(JSON.stringify({}), { - headers: { ...corsHeaders, 'Content-Type': 'application/json' }, - status: 200, - }) + return Response.json({}) } async function updateTask(supabaseClient: SupabaseClient, id: string, task: Task) { const { error } = await supabaseClient.from('tasks').update(task).eq('id', id) if (error) throw error - return new Response(JSON.stringify({ task }), { - headers: { ...corsHeaders, 'Content-Type': 'application/json' }, - status: 200, - }) + return Response.json({ task }) } async function createTask(supabaseClient: SupabaseClient, task: Task) { const { error } = await supabaseClient.from('tasks').insert(task) if (error) throw error - return new Response(JSON.stringify({ task }), { - headers: { ...corsHeaders, 'Content-Type': 'application/json' }, - status: 200, - }) + return Response.json({ task }) } -Deno.serve(async (req) => { - const { url, method } = req +export default { + fetch: withSupabase({ auth: 'user' }, async (req, ctx) => { + const { url, method } = req - // This is needed if you're planning to invoke your function from a browser. - if (method === 'OPTIONS') { - return new Response('ok', { headers: corsHeaders }) - } + try { + // ctx.supabase is scoped to the calling user, so your row-level-security + // (RLS) policies are applied. + const supabaseClient = ctx.supabase - try { - const SUPABASE_PUBLISHABLE_KEYS = JSON.parse(Deno.env.get('SUPABASE_PUBLISHABLE_KEYS')!) - // Create a Supabase client with the Auth context of the logged in user. - const supabaseClient = createClient( - // Supabase API URL - env var exported by default. - Deno.env.get('SUPABASE_URL') ?? '', - // Supabase publishable key - env var exported by default. - SUPABASE_PUBLISHABLE_KEYS['default'] ?? '', - // Create client with Auth context of the user that called the function. - // This way your row-level-security (RLS) policies are applied. - { - global: { - headers: { Authorization: req.headers.get('Authorization')! }, - }, + // For more details on URLPattern, check https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API + const taskPattern = new URLPattern({ pathname: '/restful-tasks/:id' }) + const matchingPath = taskPattern.exec(url) + const id = matchingPath ? matchingPath.pathname.groups.id : null + + let task = null + if (method === 'POST' || method === 'PUT') { + const body = await req.json() + task = body.task } - ) - // For more details on URLPattern, check https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API - const taskPattern = new URLPattern({ pathname: '/restful-tasks/:id' }) - const matchingPath = taskPattern.exec(url) - const id = matchingPath ? matchingPath.pathname.groups.id : null + // call relevant method based on method and id + switch (true) { + case id && method === 'GET': + return getTask(supabaseClient, id as string) + case id && method === 'PUT': + return updateTask(supabaseClient, id as string, task) + case id && method === 'DELETE': + return deleteTask(supabaseClient, id as string) + case method === 'POST': + return createTask(supabaseClient, task) + case method === 'GET': + return getAllTasks(supabaseClient) + default: + return getAllTasks(supabaseClient) + } + } catch (error) { + console.error(error) - let task = null - if (method === 'POST' || method === 'PUT') { - const body = await req.json() - task = body.task + return Response.json({ error: error.message }, { status: 400 }) } - - // call relevant method based on method and id - switch (true) { - case id && method === 'GET': - return getTask(supabaseClient, id as string) - case id && method === 'PUT': - return updateTask(supabaseClient, id as string, task) - case id && method === 'DELETE': - return deleteTask(supabaseClient, id as string) - case method === 'POST': - return createTask(supabaseClient, task) - case method === 'GET': - return getAllTasks(supabaseClient) - default: - return getAllTasks(supabaseClient) - } - } catch (error) { - console.error(error) - - return new Response(JSON.stringify({ error: error.message }), { - headers: { ...corsHeaders, 'Content-Type': 'application/json' }, - status: 400, - }) - } -}) + }), +} diff --git a/examples/prompts/edge-functions.md b/examples/prompts/edge-functions.md index 87447d7a997..49aa1df01e3 100644 --- a/examples/prompts/edge-functions.md +++ b/examples/prompts/edge-functions.md @@ -10,47 +10,115 @@ You're an expert in writing TypeScript and Deno JavaScript runtime. Generate **h ## Guidelines -1. Try to use Web APIs and Deno’s core APIs instead of external dependencies (eg: use fetch instead of Axios, use WebSockets API instead of node-ws) +1. Try to use Web APIs and Deno's core APIs instead of external dependencies (eg: use fetch instead of Axios, use WebSockets API instead of node-ws) 2. If you are reusing utility methods between Edge Functions, add them to `supabase/functions/_shared` and import using a relative path. Do NOT have cross dependencies between Edge Functions. 3. Do NOT use bare specifiers when importing dependencies. If you need to use an external dependency, make sure it's prefixed with either `npm:` or `jsr:`. For example, `@supabase/supabase-js` should be written as `npm:@supabase/supabase-js`. -4. For external imports, always define a version. For example, `npm:@express` should be written as `npm:express@4.18.2`. -5. For external dependencies, importing via `npm:` and `jsr:` is preferred. Minimize the use of imports from @`deno.land/x` , `esm.sh` and @`unpkg.com` . If you have a package from one of those CDNs, you can replace the CDN hostname with `npm:` specifier. -6. You can also use Node built-in APIs. You will need to import them using `node:` specifier. For example, to import Node process: `import process from "node:process". Use Node APIs when you find gaps in Deno APIs. -7. Do NOT use `import { serve } from "https://deno.land/std@0.168.0/http/server.ts"`. Instead use the built-in `Deno.serve`. -8. Following environment variables (ie. secrets) are pre-populated in both local and hosted Supabase environments. Users don't need to manually set them: +4. For external imports, always define a version. For example, `npm:express` should be written as `npm:express@4.18.2`. +5. For external dependencies, importing via `npm:` and `jsr:` is preferred. Minimize the use of imports from `deno.land/x`, `esm.sh` and `unpkg.com`. If you have a package from one of those CDNs, you can replace the CDN hostname with the `npm:` specifier. +6. You can also use Node built-in APIs. You will need to import them using the `node:` specifier. For example, to import Node process: `import process from "node:process"`. Use Node APIs when you find gaps in Deno APIs. +7. Do NOT use `import { serve } from "https://deno.land/std@0.168.0/http/server.ts"`, and do NOT use `Deno.serve`. Instead, export a default object with a `fetch` handler: + + ```ts + export default { + fetch: async (req: Request) => { + return Response.json({ message: 'Hello world' }) + }, + } + ``` + + This is the request handler contract for Supabase Edge Functions, and it also runs unchanged on Cloudflare Workers and Bun. Always wrap this handler with `withSupabase` to secure and configure it (see guideline 8). + +8. Write your handler with `withSupabase` from `npm:@supabase/server@^1`. One wrapper gives you: + - Authentication: verifies the caller's credentials. + - Authorization: only lets through callers that match the `auth` mode you declare. + - Pre-configured clients on `ctx`: `ctx.supabase` (scoped to the caller's RLS) and `ctx.supabaseAdmin` (bypasses RLS). + - CORS handling, including preflight requests. + + Your one decision is the `auth` mode: + + ```ts + import { withSupabase } from 'npm:@supabase/server@^1' + + export default { + fetch: withSupabase({ auth: 'user' }, async (req, ctx) => { + const { data, error } = await ctx.supabase.from('countries').select('*') + if (error) throw error + return Response.json({ data }) + }), + } + ``` + + Choose the `auth` mode by who calls the function: + + | Caller | `auth` | `verify_jwt` | Client | + | ---------------------------------------------------- | --------------- | ---------------------- | ---------------------------------- | + | Signed-in user (JWT on `Authorization`) | `'user'` | `true` (default, omit) | `ctx.supabase` (RLS-scoped) | + | Cron, worker, `pg_net`, or another function | `'secret'` | `false` | `ctx.supabaseAdmin` (bypasses RLS) | + | Public client | `'publishable'` | `false` | `ctx.supabase` | + | Public endpoint or external webhook (verify in code) | `'none'` | `false` | `ctx.supabaseAdmin` if needed | + + For any mode other than `'user'`, set `verify_jwt = false` for that function in `supabase/config.toml`: + + ```toml + [functions.my-function] + verify_jwt = false + ``` + + `ctx.userClaims` holds the verified user identity. To accept only one named key, use `auth: 'secret:'` or `auth: 'publishable:'`. For a public endpoint, use `auth: 'none'`; you still get CORS handling and `ctx.supabaseAdmin`. + +9. The following environment variables (ie. secrets) are pre-populated in both local and hosted Supabase environments. Users don't need to manually set them: - SUPABASE_URL - SUPABASE_PUBLISHABLE_KEYS - SUPABASE_SECRET_KEYS - SUPABASE_DB_URL -You then need to parse them with `JSON.parse(Deno.env.get('SUPABASE_SECRET_KEYS')!)` or `JSON.parse(Deno.env.get('SUPABASE_PUBLISHABLE_KEYS')!)` to access the actual keys in the code. For example, assign the parsed map first with `const SUPABASE_SECRET_KEYS = JSON.parse(Deno.env.get('SUPABASE_SECRET_KEYS')!)` and then index it with `SUPABASE_SECRET_KEYS['default']` to access the default secret key. 9. To set other environment variables (ie. secrets) users can put them in a env file and run the `supabase secrets set --env-file path/to/env-file` 10. A single Edge Function can handle multiple routes. It is recommended to use a library like Express or Hono to handle the routes as it's easier for developer to understand and maintain. Each route must be prefixed with `/function-name` so they are routed correctly. 11. File write operations are ONLY permitted on `/tmp` directory. You can use either Deno or Node File APIs. 12. Use `EdgeRuntime.waitUntil(promise)` static method to run long-running tasks in the background without blocking response to a request. Do NOT assume it is available in the request / execution context. + `withSupabase` reads these for you, so prefer it over reading keys by hand. If you must read a key without the SDK, parse the JSON map and index it by name: `const SUPABASE_SECRET_KEYS = JSON.parse(Deno.env.get('SUPABASE_SECRET_KEYS')!)`, then `SUPABASE_SECRET_KEYS['default']` for the default secret key. The publishable keys work the same way through `SUPABASE_PUBLISHABLE_KEYS`. + +10. To set other environment variables (ie. secrets) users can put them in an env file and run `supabase secrets set --env-file path/to/env-file`. +11. A single Edge Function can handle multiple routes. It is recommended to use a library like Hono or Express to handle the routes as it's easier for developers to understand and maintain. Each route must be prefixed with `/function-name` so they are routed correctly. For per-route Supabase auth with Hono, use the adapter from `npm:@supabase/server@^1/adapters/hono`. +12. File write operations are ONLY permitted on the `/tmp` directory. You can use either Deno or Node File APIs. +13. Use the `EdgeRuntime.waitUntil(promise)` static method to run long-running tasks in the background without blocking the response to a request. Do NOT assume it is available in the request / execution context. ## Example Templates +### Recommended: Edge Function with `withSupabase` + +```ts +import { withSupabase } from 'npm:@supabase/server@^1' + +export default { + fetch: withSupabase({ auth: 'user' }, async (req, ctx) => { + const { data, error } = await ctx.supabase.from('countries').select('*') + if (error) throw error + return Response.json({ data }) + }), +} +``` + ### Simple Hello World Function -```tsx +```ts interface reqPayload { name: string } console.info('server started') -Deno.serve(async (req: Request) => { - const { name }: reqPayload = await req.json() - const data = { - message: `Hello ${name} from foo!`, - } +export default { + fetch: async (req: Request) => { + const { name }: reqPayload = await req.json() + const data = { + message: `Hello ${name} from foo!`, + } - return new Response(JSON.stringify(data), { - headers: { 'Content-Type': 'application/json', Connection: 'keep-alive' }, - }) -}) + return Response.json(data) + }, +} ``` ### Example Function using Node built-in API -```tsx +```ts import { randomBytes } from 'node:crypto' import { createServer } from 'node:http' import process from 'node:process' @@ -73,7 +141,7 @@ server.listen(9999) ### Using npm packages in Functions -```tsx +```ts import express from 'npm:express@4.18.2' const app = express() @@ -87,18 +155,15 @@ app.listen(8000) ### Generate embeddings using built-in @Supabase.ai API -```tsx +```ts const model = new Supabase.ai.Session('gte-small') -Deno.serve(async (req: Request) => { - const params = new URL(req.url).searchParams - const input = params.get('text') - const output = await model.run(input, { mean_pool: true, normalize: true }) - return new Response(JSON.stringify(output), { - headers: { - 'Content-Type': 'application/json', - Connection: 'keep-alive', - }, - }) -}) +export default { + fetch: async (req: Request) => { + const params = new URL(req.url).searchParams + const input = params.get('text') + const output = await model.run(input, { mean_pool: true, normalize: true }) + return Response.json(output) + }, +} ``` From 8d49701cb0a3e2634961e5b1b2d23869e13c311c Mon Sep 17 00:00:00 2001 From: Ali Waseem Date: Mon, 8 Jun 2026 11:48:26 -0600 Subject: [PATCH 039/134] fix: clip overflowing text in collapsed sonner toasts (#46752) When multiple toasts stack up, Sonner compresses background toasts. The text content in these collapsed toasts was overflowing past the boundary and leaking into the page layout. This adds `data-[expanded=false]:overflow-hidden` to clip the overflowing text. ## Summary by CodeRabbit * **Style** * Updated toast notification styling to better handle content overflow behavior when toasts are in a collapsed state. --- packages/ui/src/components/shadcn/ui/sonner.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/ui/src/components/shadcn/ui/sonner.tsx b/packages/ui/src/components/shadcn/ui/sonner.tsx index 87d43b6fee1..65e6d63e556 100644 --- a/packages/ui/src/components/shadcn/ui/sonner.tsx +++ b/packages/ui/src/components/shadcn/ui/sonner.tsx @@ -38,6 +38,7 @@ const SonnerToaster = ({ toastOptions, ...props }: ToasterProps) => { 'items-start', 'font-normal', 'text-sm', + 'data-[expanded=false]:overflow-hidden', 'group-[.toaster]:bg-overlay group-[.toaster]:text-foreground group-[.toaster]:border group-[.toaster]:border-overlay group-[.toaster]:shadow-lg' ), icon: 'mt-0.5', From 99f0518137da8ca05cc78cb083e3488a38a573e8 Mon Sep 17 00:00:00 2001 From: Prashant Sridharan <914007+CoolAssPuppy@users.noreply.github.com> Date: Tue, 9 Jun 2026 00:40:18 +0100 Subject: [PATCH 040/134] Added a Hosted Postgres page (#46674) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Created a new solution page for Hosted Postgres. ## Summary by CodeRabbit * **New Features** * Added Hosted Postgres solution with a dedicated landing page (hero, features, pricing comparison, security, results, CTAs) * Introduced a reusable pricing comparison table component * Enhanced feature grids to support optional headers and richer icon options * **Updates** * Updated company stats (databases managed → 44M, daily launches → 200K, registered developers → 9M) * Added Hosted Postgres link to Solutions navigation * **Refactor** * Consolidated and exported component prop interfaces for cleaner prop contracts --------- Co-authored-by: Terry Sutton --- apps/www/components/Solutions/CtaSection.tsx | 11 +- apps/www/components/Solutions/FeatureGrid.tsx | 58 +- .../Solutions/PricingComparisonSection.tsx | 121 ++++ apps/www/data/Footer.ts | 4 + apps/www/data/Solutions.tsx | 9 + apps/www/data/company-stats.ts | 12 +- apps/www/data/solutions/hosted-postgres.tsx | 682 ++++++++++++++++++ apps/www/pages/solutions/hosted-postgres.tsx | 67 ++ 8 files changed, 933 insertions(+), 31 deletions(-) create mode 100644 apps/www/components/Solutions/PricingComparisonSection.tsx create mode 100644 apps/www/data/solutions/hosted-postgres.tsx create mode 100644 apps/www/pages/solutions/hosted-postgres.tsx diff --git a/apps/www/components/Solutions/CtaSection.tsx b/apps/www/components/Solutions/CtaSection.tsx index 9ea1715eac5..f3e40dde692 100644 --- a/apps/www/components/Solutions/CtaSection.tsx +++ b/apps/www/components/Solutions/CtaSection.tsx @@ -4,7 +4,7 @@ import { Button, cn } from 'ui' import SectionContainer from '@/components/Layouts/SectionContainer' -interface Props { +export interface CtaSectionProps { id: string title: string | React.ReactNode subtitle?: string @@ -25,7 +25,14 @@ interface Props { className?: string } -const CtaSection = ({ id, title, subtitle, primaryCta, secondaryCta, className }: Props) => { +const CtaSection = ({ + id, + title, + subtitle, + primaryCta, + secondaryCta, + className, +}: CtaSectionProps) => { return ( { +const FeatureGrid = ({ id, features, heading, subheading, className }: FeatureGridProps) => { return ( + {(heading || subheading) && ( +
+ {heading &&

{heading}

} + {subheading &&

{subheading}

} +
+ )}
- {feature.icon && ( - - - - )} + {feature.icon && + (typeof feature.icon === 'string' ? ( + + + + ) : ( + + ))}

{feature.title}

{feature.description}

diff --git a/apps/www/components/Solutions/PricingComparisonSection.tsx b/apps/www/components/Solutions/PricingComparisonSection.tsx new file mode 100644 index 00000000000..6af38024405 --- /dev/null +++ b/apps/www/components/Solutions/PricingComparisonSection.tsx @@ -0,0 +1,121 @@ +import { Check, Minus } from 'lucide-react' +import React, { type FC, type ReactNode } from 'react' +import { cn } from 'ui' +import { TextLink } from 'ui-patterns/TextLink' + +import SectionContainer from '@/components/Layouts/SectionContainer' + +export interface PricingComparisonPlan { + name: string + /** Highlights the column visually (eg. the recommended plan). */ + highlight?: boolean +} + +export interface PricingComparisonRow { + feature: ReactNode + /** One value per plan, in the same order as `plans`. Booleans render as a check or dash. */ + values: (ReactNode | boolean)[] +} + +export interface PricingComparisonSectionProps { + id?: string + heading: ReactNode + subheading?: ReactNode + plans: PricingComparisonPlan[] + rows: PricingComparisonRow[] + cta?: { + label: string + url: string + } + className?: string +} + +const PlanValue = ({ value }: { value: ReactNode | boolean }) => { + if (value === true) { + return + } + if (value === false) { + return ( + + ) + } + return {value} +} + +const PricingComparisonSection: FC = ({ + id, + heading, + subheading, + plans, + rows, + cta, + className, +}) => { + return ( + +
+

{heading}

+ {subheading &&

{subheading}

} +
+ +
+ + + + + {plans.map((plan) => ( + + ))} + + + + {rows.map((row, rowIndex) => ( + + + {row.values.map((value, valueIndex) => ( + + ))} + + ))} + +
+ What you get + + {plan.name} +
+ {row.feature} + + + + +
+
+ + {cta && } +
+ ) +} + +export default PricingComparisonSection diff --git a/apps/www/data/Footer.ts b/apps/www/data/Footer.ts index 5fa08c94530..19f6e136634 100644 --- a/apps/www/data/Footer.ts +++ b/apps/www/data/Footer.ts @@ -50,6 +50,10 @@ const footerData = [ { title: 'Solutions', links: [ + { + text: 'Hosted Postgres', + url: '/solutions/hosted-postgres', + }, ...skillBasedSolutions.solutions.map((solution) => ({ text: solution.text, url: solution.url, diff --git a/apps/www/data/Solutions.tsx b/apps/www/data/Solutions.tsx index 281ea1c3363..37f0ca6d486 100644 --- a/apps/www/data/Solutions.tsx +++ b/apps/www/data/Solutions.tsx @@ -2,6 +2,7 @@ import { BotIcon, Building2Icon, Code2Icon, + Database, HammerIcon, Heart, LightbulbIcon, @@ -33,6 +34,7 @@ export enum Solutions { finserv = 'finserv', healthcare = 'healthcare', agents = 'agents', + hostedPostgres = 'hosted-postgres', } export const skillBasedSolutions = { @@ -154,6 +156,13 @@ export const useCaseSolutions = { export const appTypeSolutions = { label: 'Solutions', solutions: [ + { + id: Solutions.hostedPostgres, + text: 'Hosted Postgres', + description: '', + url: '/solutions/hosted-postgres', + icon: Database, + }, { id: Solutions.b2bSaaS, text: 'B2B SaaS', diff --git a/apps/www/data/company-stats.ts b/apps/www/data/company-stats.ts index 65a4c924b06..a84ae813c93 100644 --- a/apps/www/data/company-stats.ts +++ b/apps/www/data/company-stats.ts @@ -3,18 +3,18 @@ // Number is used for animated components (eg. AnimatedCounter) export const companyStats = { databasesManaged: { - number: 16_000_000, - text: '16,000,000+', + number: 44_000_000, + text: '44,000,000+', label: 'Databases Created', }, databasesLaunchedDaily: { - number: 90_000, - text: '90,000+', + number: 200_000, + text: '200,000+', label: 'Databases launched daily', }, developersRegistered: { - number: 7_000_000, - text: '7,000,000+', + number: 9_000_000, + text: '9,000,000+', label: 'Users', }, developersRegisteredChange: { diff --git a/apps/www/data/solutions/hosted-postgres.tsx b/apps/www/data/solutions/hosted-postgres.tsx new file mode 100644 index 00000000000..1c2d1d338df --- /dev/null +++ b/apps/www/data/solutions/hosted-postgres.tsx @@ -0,0 +1,682 @@ +import { useBreakpoint } from 'common' +import { + Activity, + Blocks, + Bot, + Cable, + CalendarClock, + Code2, + Database, + DatabaseBackup, + GitBranch, + GitFork, + Globe, + HardDrive, + HeartPulse, + History, + KeyRound, + LayoutDashboard, + Lightbulb, + List, + ListOrdered, + Lock, + LockKeyhole, + Network, + Scaling, + ShieldAlert, + ShieldCheck, + Sparkles, + SquareTerminal, + Table2, + Users, + UserX, + Wallet, + Webhook, + Workflow, +} from 'lucide-react' + +import { FrameworkLink, getEditors, type HeroSection, type Metadata } from './solutions.utils' +import type { SecuritySectionProps } from '@/components/Enterprise/Security' +import { frameworks } from '@/components/Hero/HeroFrameworks' +import Logos from '@/components/logos' +import type { CtaSectionProps } from '@/components/Solutions/CtaSection' +import type { FeatureGridProps } from '@/components/Solutions/FeatureGrid' +import type { MPCSectionProps } from '@/components/Solutions/MPCSection' +import type { PricingComparisonSectionProps } from '@/components/Solutions/PricingComparisonSection' +import type { ResultsSectionProps } from '@/components/Solutions/ResultsSection' +import { TwoColumnsSectionProps } from '@/components/Solutions/TwoColumnsSection' +import { companyStats } from '@/data/company-stats' +import type { FeaturesSection } from '@/data/solutions/solutions.utils' +import { useSendTelemetryEvent } from '@/lib/telemetry' + +const TELEMETRY_LOCATION = 'Solutions: Hosted Postgres page' + +const data: () => { + metadata: Metadata + heroSection: HeroSection + why: FeaturesSection + pricing: PricingComparisonSectionProps + included: FeatureGridProps + bundled: FeatureGridProps + resultsSection: ResultsSectionProps + performanceGrid: FeatureGridProps + securitySection: SecuritySectionProps + platformUpsell: CtaSectionProps + platformStarterSection: TwoColumnsSectionProps + mcp: MPCSectionProps +} = () => { + const isXs = useBreakpoint(640) + const editors = getEditors(isXs) + const sendTelemetryEvent = useSendTelemetryEvent() + + return { + metadata: { + metaTitle: 'Hosted Postgres | Supabase', + metaDescription: + 'A managed Postgres database in seconds, free to start and just $25 a month in production. Plus a dashboard, backups, Point-in-Time Recovery, connection pooling, read replicas, and the full Postgres extension ecosystem.', + }, + heroSection: { + id: 'hero', + title: 'Hosted Postgres', + h1: <>Managed Postgres in seconds., + subheader: [ + <> + Free to start, just $25 a month in production. More than a database: backups, logs, + advisors, connection pooling, APIs, and everything you need to run Postgres in production. + The rest of the platform is ready when you need it. + , + ], + image: undefined, + ctas: [ + { + label: 'Start your project', + href: 'https://supabase.com/dashboard', + type: 'primary' as any, + onClick: () => + sendTelemetryEvent({ + action: 'start_project_button_clicked', + properties: { buttonLocation: `${TELEMETRY_LOCATION} hero` }, + }), + }, + { + label: 'Request a demo', + href: 'https://supabase.com/contact/sales', + type: 'default' as any, + onClick: () => + sendTelemetryEvent({ + action: 'request_demo_button_clicked', + properties: { buttonLocation: `${TELEMETRY_LOCATION} hero` }, + }), + }, + ], + footer: ( +
+

+ Postgres is trusted in production by teams of every size +

+ +

+ {companyStats.databasesManaged.text} databases created and{' '} + {companyStats.developersRegistered.text} developers on Supabase +

+
+ ), + }, + why: { + id: 'why-supabase', + label: '', + heading: ( + <> + Why developers choose Supabase for{' '} + hosted Postgres + + ), + subheading: + 'You came for a Postgres database. You get a fully managed one, plus the tools you would otherwise build or buy. Pure Postgres, no lock-in.', + features: [ + { + id: 'real-postgres', + icon: Database, + heading: 'Real Postgres, fully managed', + subheading: + 'Connect with psql, pgAdmin, or any standard client. Use native extensions and Row Level Security. We handle provisioning, patching, backups, and uptime.', + }, + { + id: 'free-to-start', + icon: Wallet, + heading: 'Free to start, $25 when you need more', + subheading: + 'Launch a database for free in seconds. Upgrade to Pro for daily backups, email support, and additional production features.', + }, + { + id: 'more-than-a-database', + icon: LayoutDashboard, + heading: 'More than a database, from day one', + subheading: + 'Every project ships with a Dashboard, a SQL Editor, a Table Editor, logs, performance and security advisors, and auto-generated APIs.', + }, + { + id: 'built-to-scale', + icon: Scaling, + heading: 'Built to scale, dependable under pressure', + subheading: + 'Read replicas, point-in-time recovery, and high availability when you need them.', + }, + ], + }, + pricing: { + id: 'pricing', + heading: ( + <> + Pay for Postgres, not for surprises + + ), + subheading: + 'Most hosted Postgres plans start cheap and stay just okay. Supabase is free to start and $25 a month for a production database, with no charges for reads or writes and no per-connection fees. Here is what is included at each tier.', + plans: [{ name: 'Free' }, { name: 'Pro', highlight: true }], + rows: [ + { feature: 'Monthly price', values: ['$0', '$25'] }, + { feature: 'Dedicated Postgres database', values: [true, true] }, + { feature: 'Dashboard, SQL editor, table editor', values: [true, true] }, + { feature: 'Auto-generated REST and GraphQL APIs', values: [true, true] }, + { + feature: 'Full extension ecosystem (pgvector, PostGIS, and more)', + values: [true, true], + }, + { feature: 'Connection pooling', values: [true, true] }, + { feature: 'Charges per read or write', values: ['Never', 'Never'] }, + { feature: 'Automatic daily backups', values: [false, '7-day retention'] }, + { feature: 'Point-in-Time Recovery', values: [false, 'Add-on'] }, + { feature: 'Read replicas', values: [false, 'Add-on'] }, + { feature: 'Database branching', values: [false, 'Usage-based'] }, + { feature: 'Projects never pause', values: [false, true] }, + { feature: 'Email support', values: ['Community', true] }, + ], + cta: { + label: 'See full pricing', + url: '/pricing', + }, + }, + included: { + id: 'included', + heading: 'More than a database', + subheading: + 'Backups, connection pooling, branching, observability, point-in-time recovery, and developer tools included from day one.', + features: [ + { + id: 'managed-postgres', + title: 'Fully managed Postgres', + description: + 'A dedicated Postgres instance, provisioned in seconds and kept patched and online.', + icon: Database, + }, + { + id: 'studio-dashboard', + title: 'Studio dashboard', + description: + 'Manage your database from a clean UI: browse data, inspect schema, and run queries from anywhere.', + icon: LayoutDashboard, + }, + { + id: 'table-editor', + title: 'Table editor', + description: + 'A spreadsheet-style view to create, edit, and explore tables without writing SQL.', + icon: Table2, + }, + { + id: 'sql-editor', + title: 'SQL editor', + description: + 'Write and run SQL in the browser, save snippets, and share queries with your team.', + icon: SquareTerminal, + }, + { + id: 'automatic-backups', + title: 'Automatic backups', + description: + 'Daily backups with retention, so a bad migration is never the end of the world.', + icon: DatabaseBackup, + }, + { + id: 'pitr', + title: 'Point-in-Time Recovery', + description: 'Restore to any moment, down to the second, for true disaster recovery.', + icon: History, + }, + { + id: 'connection-pooling', + title: 'Connection pooling', + description: + 'Supavisor pools and shares connections so your app scales past Postgres connection limits.', + icon: Network, + }, + { + id: 'read-replicas', + title: 'Read replicas', + description: + 'Add read-only databases in other regions to spread load and cut latency for global users.', + icon: GitFork, + }, + { + id: 'branching', + title: 'Branching', + description: + 'Spin up isolated database branches for development and preview, then merge with confidence.', + icon: GitBranch, + }, + { + id: 'migrations-cli', + title: 'Migrations and CLI', + description: ( + <> + Version-control your schema and run the full stack locally with{' '} + supabase start. + + ), + icon: SquareTerminal, + }, + { + id: 'full-sql-access', + title: 'Full SQL access', + description: + 'CTEs, triggers, foreign keys, JSONB, full-text search, stored procedures, and PL/pgSQL.', + icon: Code2, + }, + { + id: 'extension-ecosystem', + title: 'The Postgres extension ecosystem', + description: + 'pgvector, PostGIS, pg_cron, pg_stat_statements, and dozens more, one click away.', + icon: Blocks, + }, + ], + }, + bundled: { + id: 'bundled', + heading: 'Your database is an application platform', + subheading: + 'Generate APIs, schedule work, trigger workflows, manage secrets, and connect external systems without leaving Postgres.', + features: [ + { + id: 'rest-apis', + title: 'Auto-generated REST APIs', + description: + 'PostgREST turns your schema into a REST API instantly, ready for any framework.', + icon: Webhook, + }, + { + id: 'graphql', + title: 'GraphQL', + description: 'pg_graphql reflects a GraphQL API straight from your database schema.', + icon: Workflow, + }, + { + id: 'observability', + title: 'Observability and logs', + description: 'Built-in logs, reports, and query performance tools for fast debugging.', + icon: Activity, + }, + { + id: 'advisors', + title: 'Performance and Security Advisors', + description: + 'Automatic checks that flag missing indexes, slow queries, and risky access policies before they bite.', + icon: Lightbulb, + }, + { + id: 'cron', + title: 'Cron', + description: + 'Schedule recurring jobs with cron syntax, managed inside Postgres with pg_cron.', + icon: CalendarClock, + }, + { + id: 'queues', + title: 'Queues', + description: + 'A Postgres-native durable message queue with guaranteed delivery, powered by pgmq.', + icon: ListOrdered, + }, + { + id: 'vault', + title: 'Vault', + description: 'Store secrets and encryption keys securely, right in your database.', + icon: KeyRound, + }, + { + id: 'fdw', + title: 'Foreign Data Wrappers', + description: + 'Query BigQuery, Redshift, MySQL, and external APIs as if they were local tables.', + icon: Cable, + }, + { + id: 'database-webhooks', + title: 'Database webhooks', + description: + 'Trigger functions and external services automatically when your data changes.', + icon: Webhook, + }, + { + id: 'mcp-server', + title: 'MCP Server and AI Assistant', + description: 'Connect Cursor, Claude, and other AI tools directly to your database.', + icon: Bot, + }, + ], + }, + resultsSection: { + id: 'performance', + heading: ( + <> + Top performance, +
+ at any scale + + ), + subheading: + 'Supabase is Postgres, so the ceiling is Postgres. Scale compute and storage independently, add replicas, and keep query times low whether you are handling a launch spike or steady growth. You will not outgrow it and need to start over somewhere else.', + highlights: [ + { + heading: companyStats.databasesManaged.label, + subheading: companyStats.databasesManaged.text, + }, + { + heading: 'Postgres performance gains', + subheading: '20-30x', + }, + ], + }, + performanceGrid: { + id: 'performance-features', + features: [ + { + id: 'postgres-core', + title: 'Postgres at its core', + description: + 'ACID-compliant and battle-tested, trusted by startups and enterprises alike.', + icon: Database, + }, + { + id: 'scaling', + title: 'Vertical and horizontal scaling', + description: 'Scale compute and storage independently, with support for read replicas.', + icon: Scaling, + }, + { + id: 'high-performance-disk', + title: 'High-performance disk', + description: 'Fast, configurable storage tuned for demanding workloads.', + icon: HardDrive, + }, + { + id: 'multi-region', + title: 'Multi-region deployments', + description: + 'Place read replicas close to your users for global availability and low latency.', + icon: Globe, + }, + { + id: 'high-availability', + title: 'High availability', + description: 'Automatic failover and redundancy for mission-critical applications.', + icon: ShieldCheck, + }, + { + id: 'pitr-backups', + title: 'Point-in-Time Recovery and automatic backups', + description: 'Recover quickly from any failure or mistake.', + icon: DatabaseBackup, + }, + { + id: 'multigres', + title: 'Multigres is coming', + description: ( + <>Learn more about Multigres and the performance benefits you'll get when it ships. + ), + icon: Sparkles, + }, + ], + }, + securitySection: { + id: 'security', + label: 'Security', + heading: + 'Postgres is trusted for medical records, missions to the moon, and everything in between', + subheading: + 'Keep your data secure with SOC 2, HIPAA, and GDPR compliance. Your data is encrypted at rest and in transit, with built-in tools for monitoring and managing security threats.', + features: [ + { + icon: ShieldCheck, + heading: 'SOC 2 Type II certified', + }, + { + icon: HeartPulse, + heading: 'HIPAA compliant', + }, + { + icon: Lock, + heading: 'Encryption at rest and in transit', + }, + { + icon: LockKeyhole, + heading: 'SSL enforcement', + }, + { + icon: UserX, + heading: 'Network restrictions', + }, + { + icon: Users, + heading: 'Row Level Security and Role-Based Access Control', + }, + { + icon: List, + heading: 'Database audit logs', + }, + { + icon: Lightbulb, + heading: 'Security Advisors', + }, + { + icon: KeyRound, + heading: 'Multi-factor authentication', + }, + { + icon: ShieldAlert, + heading: 'DDoS protection and vulnerability management', + }, + ], + cta: { + label: 'Learn about security', + url: '/security', + }, + }, + platformUpsell: { + id: 'platform-upsell', + title: <>Postgres now. The rest of the backend when you want it., + subtitle: + 'Your hosted Postgres comes from the same platform that gives you Auth, Storage, Edge Functions, Realtime, and Vector search. Start with the database. Add the rest later without migrating, re-architecting, or changing vendors.', + primaryCta: { + label: 'Explore the full platform', + url: '/', + }, + }, + platformStarterSection: { + id: 'platform-starter', + heading: ( + <> + Choose your platform to get started in + seconds + + ), + headingRight: ( + <> + Or, start with Supabase AI Prompts{' '} + + + ), + docsUrl: 'https://supabase.com/docs/guides/getting-started/ai-prompts', + leftFooter: ( +
+ {frameworks.map((framework) => ( + + ))} +
+ ), + aiPrompts: [ + { + id: 'auth-setup', + title: 'Bootstrap Next.js app with Supabase Auth', + description: + '## Overview of implementing Supabase Auth SSR\n1. Install @supabase/supabase-js and...', + code: `1. Install @supabase/supabase-js and @supabase/ssr packages. +2. Set up environment variables. +3. Write two utility functions with \u0060createClient\u0060 functions to create a browser client and a server client. +4. Hook up middleware to refresh auth tokens +`, + language: 'markdown', + docsUrl: + 'https://supabase.com/docs/guides/getting-started/ai-prompts/nextjs-supabase-auth', + }, + { + id: 'edge-functions', + title: 'Writing Supabase Edge Functions', + description: + "You're a Supabase Postgres expert in writing row level security policies. Your purpose is to generate...", + code: `1. Try to use Web APIs and Deno's core APIs instead of external dependencies (eg: use fetch instead of Axios, use WebSockets API instead of node-ws) +2. If you are reusing utility methods between Edge Functions, add them to 'supabase/functions/_shared' and import using a relative path. Do NOT have cross dependencies between Edge Functions. +3. Do NOT use bare specifiers when importing dependecnies. If you need to use an external dependency, make sure it's prefixed with either 'npm:' or 'jsr:'. +`, + language: 'markdown', + docsUrl: 'https://supabase.com/docs/guides/getting-started/ai-prompts/edge-functions', + }, + { + id: 'declarative-db-schema', + title: 'Declarative Database Schema', + description: + "You're a Supabase Postgres expert in writing row level security policies. Your purpose is to generate...", + code: `Mandatory Instructions for Supabase Declarative Schema Management +## 1. **Exclusive Use of Declarative Schema** +-**All database schema modifications must be defined within '.sql' files located in the 'supabase/schemas/' directory.`, + language: 'markdown', + docsUrl: + 'https://supabase.com/docs/guides/getting-started/ai-prompts/declarative-database-schema', + }, + { + id: 'rls-policies', + title: 'Create RLS policies', + description: + "You're a Supabase Postgres expert in writing row level security policies. Your purpose is to generate...", + code: `You're a Supabase Postgres expert in writing row level security policies. Your purpose is to generate a policy with the constraints given by the user. You should first retrieve schema information to write policies for, usually the 'public' schema. +The output should use the following instructions: + +- The generated SQL must be valid SQL.`, + language: 'markdown', + docsUrl: + 'https://supabase.com/docs/guides/getting-started/ai-prompts/database-rls-policies', + }, + ], + }, + mcp: { + id: 'mcp', + heading: ( +
+ Supabase works seamlessly with{' '} + your favorite AI code editor +
+ ), + ctaLabel: 'Connect your AI tools', + documentationLink: '/docs/guides/getting-started/mcp', + frameworks: editors, + apiExamples: [ + { + lang: 'json', + title: 'macOS', + code: `{ +"mcpServers": { + "supabase": { + "command": "npx", + "args": [ + "-y", + "@supabase/mcp-server-supabase@latest", + "--read-only", + "--project-ref=" + ], + "env": { + "SUPABASE_ACCESS_TOKEN": "" + } + } +} +}`, + }, + { + lang: 'json', + title: 'Windows', + code: `{ +"mcpServers": { + "supabase": { + "command": "cmd", + "args": [ + "/c", + "npx", + "-y", + "@supabase/mcp-server-supabase@latest", + "--read-only", + "--project-ref=" + ], + "env": { + "SUPABASE_ACCESS_TOKEN": "" + } + } +} +}`, + }, + { + lang: 'json', + title: 'Windows (WSL)', + code: `{ +"mcpServers": { + "supabase": { + "command": "wsl", + "args": [ + "npx", + "-y", + "@supabase/mcp-server-supabase@latest", + "--read-only", + "--project-ref=" + ], + "env": { + "SUPABASE_ACCESS_TOKEN": "" + } + } +} +}`, + }, + { + lang: 'json', + title: 'Linux', + code: `{ + "mcpServers": { + "supabase": { + "command": "npx", + "args": [ + "-y", + "@supabase/mcp-server-supabase@latest", + "--read-only", + "--project-ref=" + ], + "env": { + "SUPABASE_ACCESS_TOKEN": "" + } + } + } +}`, + }, + ], + }, + } +} + +export default data diff --git a/apps/www/pages/solutions/hosted-postgres.tsx b/apps/www/pages/solutions/hosted-postgres.tsx new file mode 100644 index 00000000000..258c52b4b04 --- /dev/null +++ b/apps/www/pages/solutions/hosted-postgres.tsx @@ -0,0 +1,67 @@ +import Layout from 'components/Layouts/Default' +import ProductHeader from 'components/Sections/ProductHeader2' +import SolutionsStickyNav from 'components/SolutionsStickyNav' +import { Solutions } from 'data/Solutions' +import getContent from 'data/solutions/hosted-postgres' +import { NextPage } from 'next' +import { NextSeo } from 'next-seo' +import dynamic from 'next/dynamic' + +const WhySupabase = dynamic(() => import('components/Solutions/FeaturesSection')) +const PricingComparison = dynamic(() => import('components/Solutions/PricingComparisonSection')) +const FeatureGrid = dynamic(() => import('components/Solutions/FeatureGrid')) +const ResultsSection = dynamic(() => import('components/Solutions/ResultsSection')) +const Security = dynamic(() => import('components/Enterprise/Security')) +const CtaSection = dynamic(() => import('components/Solutions/CtaSection')) +const PlatformStarterSection = dynamic(() => import('components/Solutions/TwoColumnsSection')) +const MPCSection = dynamic(() => import('components/Solutions/MPCSection')) + +const HostedPostgresPage: NextPage = () => { + const content = getContent() + + return ( + <> + + + + + + + + + + + + + + + + + ) +} + +export default HostedPostgresPage From 575ac8c64595a082f24ab14695f223ba7c9c5e45 Mon Sep 17 00:00:00 2001 From: Jeremias Menichelli Date: Tue, 9 Jun 2026 10:39:55 +0200 Subject: [PATCH 041/134] [DOCS-979] feat(Docs): Generate new markdown files for reference pages (#46727) In this PR: - The `llms.ts` script is removed from the pipeline. It was just iterating over the sections of the SDK JSON files to generate _dummy_ text files for LLMS to consume. But with a lot of inconsistencies and mistakes. - There's a new script that builds markdown files from the SDK definition files. - The Management API now has a definition file too, it was missing before. - On the www project now there are redirects for the reference text files to the new markdown files in the docs project. - NPM scripts have received better names so that prebuild ones are smaller and all are easier to differentiate. --- apps/docs/.gitignore | 4 +- apps/docs/DEVELOPERS.md | 2 +- .../docs/app/api/guides-md/[...slug]/route.ts | 2 +- .../internals/generate-guides-markdown.ts | 8 +- apps/docs/internals/generate-gz-archive.ts | 4 +- .../internals/generate-reference-markdown.ts | 414 ++++++++++++++++++ apps/docs/next.config.mjs | 2 +- apps/docs/package.json | 19 +- apps/docs/scripts/llms.ts | 144 ------ apps/www/app/llms-full.txt/route.ts | 5 +- apps/www/app/llms.txt/route.ts | 1 + apps/www/app/llms/[slug]/route.ts | 3 +- apps/www/next.config.mjs | 4 +- 13 files changed, 444 insertions(+), 168 deletions(-) create mode 100644 apps/docs/internals/generate-reference-markdown.ts delete mode 100644 apps/docs/scripts/llms.ts diff --git a/apps/docs/.gitignore b/apps/docs/.gitignore index af74dd45e2a..eb1e923d280 100644 --- a/apps/docs/.gitignore +++ b/apps/docs/.gitignore @@ -29,8 +29,8 @@ yarn-error.log* public/sitemap.xml # Per-source llms files (generated by build:llms, served by www) public/llms/ -# Generated guide markdown files -public/docs/ +# Generated guide and reference markdown files +public/markdown/ public/docs.tar.gz # Copied examples folder diff --git a/apps/docs/DEVELOPERS.md b/apps/docs/DEVELOPERS.md index 1f0c0d0b8a9..ea96686cb08 100644 --- a/apps/docs/DEVELOPERS.md +++ b/apps/docs/DEVELOPERS.md @@ -31,7 +31,7 @@ To test locally, within the `apps/docs` directory: 1. Run `pnpm build:guides-markdown` 2. Run `pnpm dev` -This creates Markdown files for all routes under the `public/docs/guides` directory, ignored by Git. +This creates Markdown files for all routes under the `public/markdown/guides` directory, ignored by Git. For production this setup runs as a `prebuild` task to allow Vercel to bundle these files with middleware and functions. diff --git a/apps/docs/app/api/guides-md/[...slug]/route.ts b/apps/docs/app/api/guides-md/[...slug]/route.ts index 3e877b3181f..51dea28525c 100644 --- a/apps/docs/app/api/guides-md/[...slug]/route.ts +++ b/apps/docs/app/api/guides-md/[...slug]/route.ts @@ -5,7 +5,7 @@ import { NextResponse } from 'next/server' export async function GET(request: Request, { params }: { params: Promise<{ slug: string[] }> }) { const { slug } = await params - const baseDir = path.join(process.cwd(), 'public/docs/guides') + const baseDir = path.join(process.cwd(), 'public/markdown/guides') const filePath = path.join(baseDir, `${slug.join('/')}.md`) if (!filePath.startsWith(baseDir + path.sep) && filePath !== baseDir) { diff --git a/apps/docs/internals/generate-guides-markdown.ts b/apps/docs/internals/generate-guides-markdown.ts index 0e283f27aaa..8fdf3273617 100644 --- a/apps/docs/internals/generate-guides-markdown.ts +++ b/apps/docs/internals/generate-guides-markdown.ts @@ -200,7 +200,7 @@ async function generate() { await Promise.all( files.map(async (filePath) => { const outPath = filePath - .replace(/^content\/guides\//, 'public/docs/guides/') + .replace(/^content\/guides\//, 'public/markdown/guides/') .replace(/\.mdx$/, '.md') let output: string @@ -234,8 +234,8 @@ async function generate() { } } - // content/guides/ai/vector-columns.mdx → public/docs/guides/ai/vector-columns.md - // Placing under public/docs/ ensures the file is served at /docs/guides/... + // content/guides/ai/vector-columns.mdx → public/markdown/guides/ai/vector-columns.md + // Placing under public/markdown/ ensures the file is served at /docs/guides/... // matching the exact URL of the rendered page. await fs.promises.mkdir(path.dirname(outPath), { recursive: true }) await fs.promises.writeFile(outPath, output) @@ -243,7 +243,7 @@ async function generate() { ) const summary = warnings ? ` (${warnings} with warnings)` : '' - console.log(`Generated ${files.length} markdown files under public/docs/guides/${summary}`) + console.log(`Generated ${files.length} markdown files under public/markdown/guides/${summary}`) } generate() diff --git a/apps/docs/internals/generate-gz-archive.ts b/apps/docs/internals/generate-gz-archive.ts index 4e57d219ccd..491f85441f1 100644 --- a/apps/docs/internals/generate-gz-archive.ts +++ b/apps/docs/internals/generate-gz-archive.ts @@ -5,9 +5,9 @@ async function generate() { // Create a tar.gz archive of the generated docs, served at /docs/docs.tar.gz. // Sorted entries, portable headers, and a fixed mtime keep the output deterministic. const archivePath = 'public/docs.tar.gz' - const entries = (await globby(['**'], { cwd: 'public/docs' })).sort() + const entries = (await globby(['**'], { cwd: 'public/markdown' })).sort() await createTar( - { gzip: true, file: archivePath, cwd: 'public/docs', portable: true, mtime: new Date() }, + { gzip: true, file: archivePath, cwd: 'public/markdown', portable: true, mtime: new Date() }, entries ) console.log(`Created archive at ${archivePath}`) diff --git a/apps/docs/internals/generate-reference-markdown.ts b/apps/docs/internals/generate-reference-markdown.ts new file mode 100644 index 00000000000..f216ff89e52 --- /dev/null +++ b/apps/docs/internals/generate-reference-markdown.ts @@ -0,0 +1,414 @@ +import fs from 'node:fs/promises' +import path from 'node:path' +import matter from 'gray-matter' +import yaml from 'js-yaml' + +const GENERATED = path.join(process.cwd(), 'features/docs/generated') +const OUT_DIR = path.join(process.cwd(), 'public/markdown/reference') +const MDX_ROOT = path.join(process.cwd(), 'docs/ref') + +type Section = { + id?: string + title?: string + slug?: string + type?: string + items?: Section[] +} + +type Example = { name?: string; code?: string } + +type LegacyFn = { + id: string + $ref?: string + title?: string + description?: string + notes?: string + examples?: Example[] +} + +type TypeSpec = { + methods: Record +} + +type RefBase = { + title: string + outFile: string + /** Folder under docs/ref/ that holds .mdx sections for `type: "markdown"` entries. */ + mdxDir: string +} + +type SdkLegacyRef = RefBase & { + kind: 'sdk-legacy' + sectionsPath: string + functionsPath: string +} + +type SdkNewRef = RefBase & { + kind: 'sdk-new' + contentDir: string +} + +type ApiRef = RefBase & { + kind: 'api' + sectionsPath: string + endpointsByIdPath: string +} + +type CliRef = RefBase & { + kind: 'cli' + sectionsPath: string + cliSpecPath: string +} + +type Ref = SdkLegacyRef | SdkNewRef | ApiRef | CliRef + +const REFERENCES: Ref[] = [ + { + kind: 'api', + title: 'Management API Reference', + outFile: 'api.md', + mdxDir: path.join(MDX_ROOT, 'api'), + sectionsPath: path.join(GENERATED, 'api.latest.sections.json'), + endpointsByIdPath: path.join(GENERATED, 'api.latest.endpointsById.json'), + }, + { + kind: 'cli', + title: 'Supabase CLI Reference', + outFile: 'cli.md', + mdxDir: path.join(MDX_ROOT, 'cli'), + sectionsPath: path.join(GENERATED, 'cli.latest.sections.json'), + cliSpecPath: path.join(process.cwd(), 'spec/cli_v1_commands.yaml'), + }, + { + kind: 'sdk-new', + title: 'JavaScript Client Library Reference', + outFile: 'js.md', + mdxDir: path.join(MDX_ROOT, 'javascript'), + contentDir: path.join(process.cwd(), 'content/reference/javascript/v2'), + }, + { + kind: 'sdk-legacy', + title: 'Dart Client Library Reference', + outFile: 'dart.md', + mdxDir: path.join(MDX_ROOT, 'dart'), + sectionsPath: path.join(GENERATED, 'dart.v2.sections.json'), + functionsPath: path.join(GENERATED, 'dart.v2.functions.json'), + }, + { + kind: 'sdk-legacy', + title: 'Kotlin Client Library Reference', + outFile: 'kotlin.md', + mdxDir: path.join(MDX_ROOT, 'kotlin'), + sectionsPath: path.join(GENERATED, 'kotlin.v1.sections.json'), + functionsPath: path.join(GENERATED, 'kotlin.v1.functions.json'), + }, + { + kind: 'sdk-legacy', + title: 'Python Client Library Reference', + outFile: 'python.md', + mdxDir: path.join(MDX_ROOT, 'python'), + sectionsPath: path.join(GENERATED, 'python.v2.sections.json'), + functionsPath: path.join(GENERATED, 'python.v2.functions.json'), + }, + { + kind: 'sdk-legacy', + title: 'Swift Client Library Reference', + outFile: 'swift.md', + mdxDir: path.join(MDX_ROOT, 'swift'), + sectionsPath: path.join(GENERATED, 'swift.v2.sections.json'), + functionsPath: path.join(GENERATED, 'swift.v2.functions.json'), + }, + { + kind: 'sdk-legacy', + title: 'C# Client Library Reference', + outFile: 'csharp.md', + mdxDir: path.join(MDX_ROOT, 'csharp'), + sectionsPath: path.join(GENERATED, 'csharp.v0.sections.json'), + functionsPath: path.join(GENERATED, 'csharp.v0.functions.json'), + }, +] + +function flatten(sections: Section[]): Section[] { + return sections.flatMap((s) => (s.items ? [s, ...flatten(s.items)] : [s])) +} + +async function readJson(filePath: string): Promise { + return JSON.parse(await fs.readFile(filePath, 'utf8')) as T +} + +function renderExamples(examples: Example[] | undefined): string { + if (!examples?.length) return '' + const blocks = examples + .map((ex) => { + const header = ex.name ? `#### ${ex.name}\n\n` : '' + const code = (ex.code ?? '').trim() + return code ? `${header}${code}` : header.trim() + }) + .filter(Boolean) + return blocks.length ? `### Examples\n\n${blocks.join('\n\n')}` : '' +} + +function renderFunctionSection(args: { + title: string + description?: string + notes?: string + examples?: Example[] +}): string { + const parts = [`## ${args.title}`] + if (args.description?.trim()) parts.push(args.description.trim()) + if (args.notes?.trim()) parts.push(args.notes.trim()) + const examples = renderExamples(args.examples) + if (examples) parts.push(examples) + return parts.join('\n\n') +} + +/** Remove the minimum common leading whitespace from all non-empty lines. */ +function dedentBlock(text: string): string { + const lines = text.split('\n') + const nonEmpty = lines.filter((l) => /\S/.test(l)) + if (!nonEmpty.length) return text + const minIndent = Math.min(...nonEmpty.map((l) => (l.match(/^([ \t]*)/) ?? ['', ''])[1].length)) + if (!minIndent) return text + return lines.map((l) => l.slice(minIndent)).join('\n') +} + +/** + * Strip MDX comments and JSX component tags while keeping inner prose/code. + * Outside code fences, leading whitespace from JSX nesting is removed. Inside + * code fences, the body is dedented so the closing fence sits flush left. + */ +function stripMdxJsx(content: string): string { + const segments = content.split(/(```[\s\S]*?```)/g) + return segments + .map((seg, i) => { + if (i % 2 === 0) { + let prose = seg + prose = prose.replace(/\{\/\*[\s\S]*?\*\/\}/g, '') + prose = prose.replace(/<[$A-Z][\w.]*(?:\s[^>]*)?\s*\/>/gs, '') + prose = prose.replace(/<[$A-Z][\w.]*(?:\s[^>]*)?\s*>/gs, '') + prose = prose.replace(/<\/[$A-Z][\w.]*>/g, '') + prose = prose.replace(/<\/?(?:div|a|span|p|h[1-6])(?:\s[^>]*)?\s*>/g, '') + return prose.replace(/^[ \t]+/gm, '') + } + return seg.replace( + /^(```[^\n]*\n)([\s\S]*?)(\n[ \t]*```)$/, + (_, open, body) => open + dedentBlock(body) + '\n```' + ) + }) + .join('') + .replace(/^[^\S\n]+$/gm, '') + .replace(/\n{3,}/g, '\n\n') + .trim() +} + +/** + * Read a `type: "markdown"` section's .mdx file and convert it to plain + * markdown. Returns null if the file doesn't exist or has no usable content. + */ +async function renderMarkdownSection(mdxDir: string, section: Section): Promise { + if (!section.slug) return null + let raw: string + try { + raw = await fs.readFile(path.join(mdxDir, `${section.slug}.mdx`), 'utf8') + } catch { + return null + } + const { content, data } = matter(raw) + const body = stripMdxJsx(content) + if (!body) return null + const heading = data.hideTitle + ? null + : ((typeof data.title === 'string' ? data.title : section.title) ?? null) + return heading ? `## ${heading}\n\n${body}` : body +} + +async function renderSdkLegacy(ref: SdkLegacyRef, sharedTypeSpec: TypeSpec): Promise { + const [sections, functions] = await Promise.all([ + readJson(ref.sectionsPath), + readJson(ref.functionsPath), + ]) + const fnsById = new Map(functions.map((fn) => [fn.id, fn])) + const methodsByRef = new Map(Object.entries(sharedTypeSpec.methods ?? {})) + + const parts: string[] = [`# ${ref.title}`] + for (const section of flatten(sections)) { + if (section.type === 'category' && section.title) { + parts.push(`## ${section.title}`) + continue + } + if (section.type === 'markdown') { + const md = await renderMarkdownSection(ref.mdxDir, section) + if (md) parts.push(md) + continue + } + if (section.type !== 'function' || !section.id) continue + const fn = fnsById.get(section.id) + if (!fn) continue + const tsm = fn.$ref ? methodsByRef.get(fn.$ref) : undefined + parts.push( + renderFunctionSection({ + title: fn.title || section.title || fn.id, + description: fn.description ?? tsm?.comment?.shortText, + notes: fn.notes, + examples: fn.examples ?? tsm?.comment?.examples, + }) + ) + } + return parts.join('\n\n') + '\n' +} + +async function renderSdkNew(ref: SdkNewRef): Promise { + const [sections, functions, typeSpec] = await Promise.all([ + readJson(path.join(ref.contentDir, 'sections.json')), + readJson(path.join(ref.contentDir, 'functions.json')), + readJson(path.join(ref.contentDir, 'typeSpec.json')), + ]) + const fnsById = new Map(functions.map((fn) => [fn.id, fn])) + const methods = typeSpec.methods ?? {} + + const parts: string[] = [`# ${ref.title}`] + for (const section of flatten(sections)) { + if (section.type === 'category' && section.title) { + parts.push(`## ${section.title}`) + continue + } + if (section.type === 'markdown') { + const md = await renderMarkdownSection(ref.mdxDir, section) + if (md) parts.push(md) + continue + } + if (section.type !== 'function' || !section.id) continue + const fn = fnsById.get(section.id) + if (!fn) continue + const tsm = fn.$ref ? methods[fn.$ref] : undefined + parts.push( + renderFunctionSection({ + title: fn.title || section.title || fn.id, + description: fn.description ?? tsm?.comment?.shortText, + notes: fn.notes, + examples: fn.examples ?? tsm?.comment?.examples, + }) + ) + } + return parts.join('\n\n') + '\n' +} + +async function renderApi(ref: ApiRef): Promise { + type Endpoint = { + summary?: string + description?: string + path?: string + method?: string + parameters?: Array<{ + name: string + required?: boolean + description?: string + schema?: { type?: string } + }> + } + const [sections, entries] = await Promise.all([ + readJson(ref.sectionsPath), + readJson>(ref.endpointsByIdPath), + ]) + const endpointsById = new Map(entries) + + const parts: string[] = [`# ${ref.title}`] + for (const section of flatten(sections)) { + if (section.type === 'category' && section.title) { + parts.push(`## ${section.title}`) + continue + } + if (section.type === 'markdown') { + const md = await renderMarkdownSection(ref.mdxDir, section) + if (md) parts.push(md) + continue + } + if (section.type !== 'operation' || !section.id) continue + const ep = endpointsById.get(section.id) + if (!ep) continue + const heading = ep.summary || section.title || section.id + const block = [`## ${heading}`] + if (ep.path) block.push(`\`${(ep.method ?? 'GET').toUpperCase()} ${ep.path}\``) + if (ep.description?.trim()) block.push(ep.description.trim()) + if (ep.parameters?.length) { + const list = ep.parameters + .map((p) => { + const required = p.required ? 'required' : 'optional' + const type = p.schema?.type ?? 'string' + return `- \`${p.name}\` (${type}, ${required})${p.description ? `: ${p.description}` : ''}` + }) + .join('\n') + block.push(`### Parameters\n\n${list}`) + } + parts.push(block.join('\n\n')) + } + return parts.join('\n\n') + '\n' +} + +async function renderCli(ref: CliRef): Promise { + type Command = { + id: string + title?: string + summary?: string + description?: string + usage?: string + } + const [sections, spec] = await Promise.all([ + readJson(ref.sectionsPath), + fs.readFile(ref.cliSpecPath, 'utf8').then((raw) => yaml.load(raw) as { commands: Command[] }), + ]) + const cmdsById = new Map((spec.commands ?? []).map((c) => [c.id, c])) + + const parts: string[] = [`# ${ref.title}`] + for (const section of flatten(sections)) { + if (section.type === 'category' && section.title) { + parts.push(`## ${section.title}`) + continue + } + if (section.type === 'markdown') { + const md = await renderMarkdownSection(ref.mdxDir, section) + if (md) parts.push(md) + continue + } + if (section.type !== 'cli-command' || !section.id) continue + const cmd = cmdsById.get(section.id) + if (!cmd) continue + const block = [`## ${cmd.summary || cmd.title || section.title || section.id}`] + if (cmd.description?.trim()) block.push(cmd.description.trim()) + if (cmd.usage?.trim()) block.push('```sh\n' + cmd.usage.trim() + '\n```') + parts.push(block.join('\n\n')) + } + return parts.join('\n\n') + '\n' +} + +async function generate() { + await fs.mkdir(OUT_DIR, { recursive: true }) + const sharedTypeSpec = await readJson( + path.join(process.cwd(), 'content/reference/javascript/v2/typeSpec.json') + ) + + await Promise.all( + REFERENCES.map(async (ref) => { + let output: string + switch (ref.kind) { + case 'sdk-legacy': + output = await renderSdkLegacy(ref, sharedTypeSpec) + break + case 'sdk-new': + output = await renderSdkNew(ref) + break + case 'api': + output = await renderApi(ref) + break + case 'cli': + output = await renderCli(ref) + break + } + await fs.writeFile(path.join(OUT_DIR, ref.outFile), output) + }) + ) + + console.log(`Generated ${REFERENCES.length} markdown files under public/markdown/reference/`) +} + +generate() diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs index 9243af773b2..8fa45e13c6d 100644 --- a/apps/docs/next.config.mjs +++ b/apps/docs/next.config.mjs @@ -61,7 +61,7 @@ const nextConfig = { ], outputFileTracingIncludes: { '/api/crawlers': ['./features/docs/generated/**/*', './docs/ref/**/*'], - '/api/guides-md/**/*': ['./public/docs/guides/**/*'], + '/api/guides-md/**/*': ['./public/markdown/guides/**/*'], '/guides/**/*': ['./content/guides/**/*', './content/troubleshooting/**/*', './examples/**/*'], '/reference/**/*': ['./features/docs/generated/**/*', './docs/ref/**/*'], }, diff --git a/apps/docs/package.json b/apps/docs/package.json index baef799f723..bf086e3a985 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -6,16 +6,19 @@ "scripts": { "build": "next build", "build:analyze": "ANALYZE=true next build", - "build:llms": "tsx --conditions=react-server ./scripts/llms.ts", "build:guides-markdown": "tsx ./internals/generate-guides-markdown.ts", + "prebuild:reference-markdown": "pnpm run codegen:references", + "build:reference-markdown": "tsx ./internals/generate-reference-markdown.ts", + "build:markdown": "pnpm build:guides-markdown && pnpm build:reference-markdown", "build:gz-archive": "tsx ./internals/generate-gz-archive.ts", "build:sitemap": "tsx ./internals/generate-sitemap.ts", "clean": "rimraf .next .turbo node_modules features/docs/generated examples __generated__", "codegen:examples": "shx cp -r ../../examples ./examples", "codegen:graphql": "tsx --conditions=react-server ./scripts/graphqlSchema.ts && graphql-codegen --config codegen.ts", - "codegen:references:ensure": "test -f spec/reference/javascript/v2/supabase.json || (cd spec && make download.tsdoc.v2)", - "codegen:references:new": "pnpm run codegen:references:ensure && tsx scripts/build-reference-content.ts", - "codegen:references": "tsx features/docs/Reference.generated.script.ts", + "codegen:references:new:ensure": "test -f spec/reference/javascript/v2/supabase.json || (cd spec && make download.tsdoc.v2)", + "codegen:references:new": "pnpm run codegen:references:new:ensure && tsx scripts/build-reference-content.ts", + "codegen:references:legacy": "tsx features/docs/Reference.generated.script.ts", + "codegen:references": "pnpm codegen:references:legacy && pnpm codegen:references:new", "codemod:frontmatter": "node ./scripts/codemod/mdx-meta.mjs && prettier --cache --write \"content/**/*.mdx\"", "dev": "concurrently --kill-others \"next dev --port 3001\" \"pnpm run dev:watch:troubleshooting\"", "dev:secrets:pull": "AWS_PROFILE=supa-dev node ../../scripts/getSecrets.js -n local/docs", @@ -28,10 +31,10 @@ "last-changed:reset": "pnpm run last-changed -- --reset", "lint": "eslint .", "lint:mdx": "supa-mdx-lint content --config ../../supa-mdx-lint.config.toml", - "postbuild": "pnpm run build:sitemap && pnpm run build:llms && ./../../scripts/upload-static-assets.sh", - "prebuild": "pnpm run codegen:graphql && pnpm run codegen:references && pnpm run codegen:references:new && pnpm run codegen:examples && pnpm run build:guides-markdown && pnpm run build:gz-archive", - "predev": "pnpm run codegen:graphql && pnpm run codegen:references && pnpm run codegen:references:new && pnpm run codegen:examples", - "preembeddings": "pnpm run codegen:references && pnpm run codegen:references:new", + "postbuild": "pnpm run build:sitemap && ./../../scripts/upload-static-assets.sh", + "prebuild": "pnpm run codegen:graphql && pnpm run codegen:references && pnpm run codegen:examples && pnpm run build:markdown && pnpm run build:gz-archive", + "predev": "pnpm run codegen:graphql && pnpm run codegen:references && pnpm run codegen:examples", + "preembeddings": "pnpm run codegen:references", "preinstall": "npx only-allow pnpm", "presync": "pnpm run codegen:graphql", "pretest": "pnpm run codegen:examples", diff --git a/apps/docs/scripts/llms.ts b/apps/docs/scripts/llms.ts deleted file mode 100644 index 441638c01e9..00000000000 --- a/apps/docs/scripts/llms.ts +++ /dev/null @@ -1,144 +0,0 @@ -import './utils/dotenv.js' -import 'dotenv/config' - -import fs from 'node:fs/promises' -import { fileURLToPath } from 'node:url' - -import { isFeatureEnabled } from '../../../packages/common/enabled-features/index.js' -import { - fetchCliLibReferenceSource, - fetchCSharpLibReferenceSource, - fetchDartLibReferenceSource, - fetchGuideSources, - fetchJsLibReferenceSource, - fetchKtLibReferenceSource, - fetchPythonLibReferenceSource, - fetchSwiftLibReferenceSource, - type SearchSource, -} from './search/sources/index.js' - -interface Source { - title: string - /** - * Path relative to https://supabase.com. No leading slash - */ - relPath: string - fetch: () => Promise - enabled: boolean -} - -const { - sdkCsharp: sdkCsharpEnabled, - sdkDart: sdkDartEnabled, - sdkKotlin: sdkKotlinEnabled, - sdkPython: sdkPythonEnabled, - sdkSwift: sdkSwiftEnabled, -} = isFeatureEnabled(['sdk:csharp', 'sdk:dart', 'sdk:kotlin', 'sdk:python', 'sdk:swift']) - -const SOURCES: Source[] = [ - { - title: 'Supabase Guides', - relPath: 'llms/guides.txt', - fetch: fetchGuideSources, - enabled: true, - }, - { - title: 'Supabase Reference (JavaScript)', - relPath: 'llms/js.txt', - fetch: async () => - (await fetchJsLibReferenceSource()).filter( - (item): item is SearchSource => item !== undefined - ), - enabled: true, - }, - { - title: 'Supabase Reference (Dart)', - relPath: 'llms/dart.txt', - fetch: async () => - (await fetchDartLibReferenceSource()).filter( - (item): item is SearchSource => item !== undefined - ), - enabled: sdkDartEnabled, - }, - { - title: 'Supabase Reference (Swift)', - relPath: 'llms/swift.txt', - fetch: async () => - (await fetchSwiftLibReferenceSource()).filter( - (item): item is SearchSource => item !== undefined - ), - enabled: sdkSwiftEnabled, - }, - { - title: 'Supabase Reference (Kotlin)', - relPath: 'llms/kotlin.txt', - fetch: async () => - (await fetchKtLibReferenceSource()).filter( - (item): item is SearchSource => item !== undefined - ), - enabled: sdkKotlinEnabled, - }, - { - title: 'Supabase Reference (Python)', - relPath: 'llms/python.txt', - fetch: async () => - (await fetchPythonLibReferenceSource()).filter( - (item): item is SearchSource => item !== undefined - ), - enabled: sdkPythonEnabled, - }, - { - title: 'Supabase Reference (C#)', - relPath: 'llms/csharp.txt', - fetch: async () => - (await fetchCSharpLibReferenceSource()).filter( - (item): item is SearchSource => item !== undefined - ), - enabled: sdkCsharpEnabled, - }, - { - title: 'Supabase CLI Reference', - relPath: 'llms/cli.txt', - fetch: async () => - (await fetchCliLibReferenceSource()).filter( - (item): item is SearchSource => item !== undefined - ), - enabled: true, - }, -] - -async function generateLlmsTxt() { - try { - await fs.mkdir('public/llms', { recursive: true }) - - const enabledSources = SOURCES.filter((source) => source.enabled !== false) - - const fetchedSources = await Promise.all( - enabledSources.map(async (sourceDefn) => { - const source = await sourceDefn.fetch() - const sourceText = source - .map((section) => { - section.process() - return section.extractIndexedContent() - }) - .join('\n\n') - return { defn: sourceDefn, text: sourceText } - }) - ) - - await Promise.all( - fetchedSources.map(({ defn, text }) => - fs.writeFile(`public/${defn.relPath}`, `${defn.title}\n\n${text}`) - ) - ) - } catch (err) { - console.error(err) - throw err - } -} - -if (process.argv[1] === fileURLToPath(import.meta.url)) { - generateLlmsTxt() -} - -export { generateLlmsTxt, SOURCES } diff --git a/apps/www/app/llms-full.txt/route.ts b/apps/www/app/llms-full.txt/route.ts index ca14a785f0d..d09119bdc14 100644 --- a/apps/www/app/llms-full.txt/route.ts +++ b/apps/www/app/llms-full.txt/route.ts @@ -18,7 +18,7 @@ interface Source { * included in the serverless bundle via outputFileTracingIncludes in * next.config.mjs so reads work on Vercel. */ -const GUIDES_MD_DIR = path.join(process.cwd(), '..', 'docs', 'public', 'docs', 'guides') +const GUIDES_MD_DIR = path.join(process.cwd(), '..', 'docs', 'public', 'markdown', 'guides') function getSources(): Source[] { const { sdkCsharp, sdkDart, sdkKotlin, sdkPython, sdkSwift } = isFeatureEnabled([ @@ -37,6 +37,7 @@ function getSources(): Source[] { { title: 'Supabase Reference (Python)', slug: 'python', enabled: sdkPython }, { title: 'Supabase Reference (C#)', slug: 'csharp', enabled: sdkCsharp }, { title: 'Supabase CLI Reference', slug: 'cli', enabled: true }, + { title: 'Supabase Management API Reference', slug: 'api', enabled: true }, ] } @@ -64,7 +65,7 @@ async function fetchSourceContent(slug: string): Promise { const docsUrl = process.env.NEXT_PUBLIC_DOCS_URL if (!docsUrl) return null - const response = await fetch(`${docsUrl}/llms/${slug}.txt`) + const response = await fetch(`${docsUrl}/markdown/reference/${slug}.md`) if (!response.ok) return null return response.text() diff --git a/apps/www/app/llms.txt/route.ts b/apps/www/app/llms.txt/route.ts index 12a6baeea4a..340c7eb7877 100644 --- a/apps/www/app/llms.txt/route.ts +++ b/apps/www/app/llms.txt/route.ts @@ -68,6 +68,7 @@ async function getSources(): Promise { { title: 'Supabase Reference (Python)', relPath: 'llms/python.txt', enabled: sdkPython }, { title: 'Supabase Reference (C#)', relPath: 'llms/csharp.txt', enabled: sdkCsharp }, { title: 'Supabase CLI Reference', relPath: 'llms/cli.txt', enabled: true }, + { title: 'Supabase Management API Reference', relPath: 'llms/api.txt', enabled: true }, ] } diff --git a/apps/www/app/llms/[slug]/route.ts b/apps/www/app/llms/[slug]/route.ts index 08b6678478c..376a5186b46 100644 --- a/apps/www/app/llms/[slug]/route.ts +++ b/apps/www/app/llms/[slug]/route.ts @@ -28,7 +28,8 @@ export async function GET(_request: Request, { params }: { params: Promise<{ slu const docsUrl = process.env.NEXT_PUBLIC_DOCS_URL if (docsUrl) { - const response = await fetch(`${docsUrl}/llms/${slug}`) + const filename = slug.replace(/\.txt$/, '.md') + const response = await fetch(`${docsUrl}/markdown/reference/${filename}`) if (response.ok) { const content = await response.text() return textResponse(content) diff --git a/apps/www/next.config.mjs b/apps/www/next.config.mjs index e23f23e0b98..9286c3c07af 100644 --- a/apps/www/next.config.mjs +++ b/apps/www/next.config.mjs @@ -75,12 +75,12 @@ const nextConfig = { * /llms.txt enumerates top-level guide directories at runtime via fs.readdir * on apps/docs/content/guides and reads each .mdx for its frontmatter * title. /llms-full.txt recursively reads the generated .md files under - * apps/docs/public/docs/guides. Both directories live in a sibling app, so + * apps/docs/public/markdown/. Both directories live in a sibling app, so * they have to be explicitly traced into this lambda's bundle. */ outputFileTracingIncludes: { '/llms.txt': ['../docs/content/guides/*'], - '/llms-full.txt': ['../docs/public/docs/guides/**/*.md'], + '/llms-full.txt': ['../docs/public/markdown/guides/**/*.md' ], }, reactStrictMode: true, images: { From 9ff7988c5c4ddbd246be0c05cee757ae6a47ae24 Mon Sep 17 00:00:00 2001 From: Chase Cresgy <47046876+theccres@users.noreply.github.com> Date: Tue, 9 Jun 2026 11:33:07 +0200 Subject: [PATCH 042/134] Offboarding from humans.txt (#46764) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Offboarding ## Summary by CodeRabbit * **Chores** * Updated team contributor information in public-facing documentation. --- apps/docs/public/humans.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/docs/public/humans.txt b/apps/docs/public/humans.txt index c2f9a44d4ff..88c75b2bbd1 100644 --- a/apps/docs/public/humans.txt +++ b/apps/docs/public/humans.txt @@ -22,7 +22,6 @@ Ana Mogul Andrew Valleteau Andrey A Angelico de los Reyes -Anna Weihl Ant Evans Ant Wilson Ariuna K From cd52669f1ffa8116a0f61959d73eff113de457ab Mon Sep 17 00:00:00 2001 From: Pamela Chia Date: Tue, 9 Jun 2026 17:49:35 +0800 Subject: [PATCH 043/134] fix(docs): negotiate /guides/* markdown via shared helper (#45432) ## Summary This brings docs `/guides/*` to full content negotiation for AI agents (GROWTH-811): RFC 9110 q-value parsing instead of a `.includes('text/markdown')` substring match, a 406 when the client rejects every type the route can produce, and markdown rewrites for known LLM user agents. I implemented it by extracting the negotiation into a shared `common/markdown-negotiation` module consumed by both `apps/docs/middleware.ts` and `apps/www/middleware.ts`, rather than duplicating the helpers into docs and keeping them in sync by hand with www (#45394). Single source of truth, no re-sync burden. www is refactored onto the shared helper with no behavior change. ## Changes ### docs `/guides/*` content negotiation (GROWTH-811) - Replace the `.includes('text/markdown')` substring match with RFC 9110 q-value parsing. - Return 406 (`Cache-Control: no-store`, `Vary: Accept`) when Accept excludes every type the route serves. Bypassed for LLM user agents, the `.md` suffix, and clients sending no Accept. - Rewrite to `/api/guides-md/` for LLM user agents (Claude-User, Claude-Web, ChatGPT-User, PerplexityBot) regardless of Accept. - Preserve the existing `.md` suffix routing and the entire `/reference/*` block. ### Shared negotiation helper - New `packages/common/markdown-negotiation.ts`: `negotiateMarkdown(signals, route)` returns `'markdown' | 'not-acceptable' | 'pass'`. Internalizes q-value parsing, the LLM user-agent match, the UA-length cap, and the markdown-vs-html preference. - `apps/www/middleware.ts`: refactored to consume the shared helper; its duplicated copy of the negotiation helpers (added in #45394) is removed. `.md` early-return, changelog routing, and first-referrer cookie stamping are unchanged (no behavior change, covered by its existing tests). ### Tests - New `apps/docs/middleware.test.ts`: q-value priority, the 406 path, `.md` suffix, LLM UA override, browser default Accept, training-crawler and substring-embed exclusion, and the `/reference/*` exemption. - New `packages/common/markdown-negotiation.test.ts`: the same decision matrix at the unit level (q-values, 406, LLM UAs, `.md`, `*/*`, training crawlers, OWS, out-of-range q). ## Testing (Vercel preview) After Vercel posts a preview URL, save it once then run the probe set. ```bash echo 'PREVIEW_HOST' > /tmp/growth-811-host.txt HOST=$(cat /tmp/growth-811-host.txt) # 1) Browser-style Accept -> HTML 200 curl -sI -A "Mozilla/5.0" \ -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' \ "https://$HOST/docs/guides/auth" # 2) Accept: text/markdown -> markdown 200 curl -sI -H 'Accept: text/markdown' "https://$HOST/docs/guides/auth" # 3) text/html;q=1.0, text/markdown;q=0.5 -> HTML 200 curl -sI -H 'Accept: text/html;q=1.0, text/markdown;q=0.5' "https://$HOST/docs/guides/auth" # 4) unsupported Accept -> 406 + Cache-Control: no-store + Vary: Accept curl -sI -H 'Accept: application/x-content-negotiation-probe' "https://$HOST/docs/guides/auth" # 5) User-Agent: Claude-User/1.0 (any Accept) -> markdown 200 curl -sI -A 'Claude-User/1.0' "https://$HOST/docs/guides/auth" ``` ### After merge Run [acceptmarkdown.com/readiness-check](https://acceptmarkdown.com/readiness-check) against `https://supabase.com/docs/guides/auth`: expect 100/100. ## Linear - fixes GROWTH-811 --- apps/docs/middleware.test.ts | 150 +++++++++++++++++ apps/docs/middleware.ts | 44 +++-- apps/www/middleware.ts | 78 ++------- packages/common/markdown-negotiation.test.ts | 167 +++++++++++++++++++ packages/common/markdown-negotiation.ts | 86 ++++++++++ 5 files changed, 443 insertions(+), 82 deletions(-) create mode 100644 apps/docs/middleware.test.ts create mode 100644 packages/common/markdown-negotiation.test.ts create mode 100644 packages/common/markdown-negotiation.ts diff --git a/apps/docs/middleware.test.ts b/apps/docs/middleware.test.ts new file mode 100644 index 00000000000..9e447e4afb8 --- /dev/null +++ b/apps/docs/middleware.test.ts @@ -0,0 +1,150 @@ +import { NextRequest } from 'next/server' +import { describe, expect, it } from 'vitest' + +import { middleware } from './middleware' + +// BASE_PATH defaults to '/docs' when NEXT_PUBLIC_BASE_PATH is unset, so test +// paths include the /docs prefix to match the middleware's GUIDES_PATH check. +function makeRequest( + path: string, + { accept, userAgent }: { accept?: string; userAgent?: string } = {} +): NextRequest { + const headers: Record = {} + if (accept) headers.accept = accept + if (userAgent) headers['user-agent'] = userAgent + return new NextRequest(new URL(path, 'https://supabase.com'), { headers }) +} + +const REWRITE_HEADER = 'x-middleware-rewrite' +const GUIDES_MD_REWRITE = (slug: string) => `https://supabase.com/docs/api/guides-md/${slug}` + +describe('docs middleware — /guides/* content negotiation', () => { + it('rewrites to /api/guides-md/ when Accept includes text/markdown', () => { + const req = makeRequest('/docs/guides/auth', { accept: 'text/markdown' }) + expect(middleware(req).headers.get(REWRITE_HEADER)).toBe(GUIDES_MD_REWRITE('auth')) + }) + + it('rewrites /.md to /api/guides-md/ regardless of Accept', () => { + for (const accept of [undefined, 'text/html']) { + const req = makeRequest('/docs/guides/auth.md', accept ? { accept } : {}) + expect(middleware(req).headers.get(REWRITE_HEADER)).toBe(GUIDES_MD_REWRITE('auth')) + } + }) + + it('serves HTML for browser-style Accept', () => { + const req = makeRequest('/docs/guides/auth', { + accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', + }) + expect(middleware(req).headers.get(REWRITE_HEADER)).toBeNull() + }) + + it('serves markdown when md q-value beats html', () => { + const req = makeRequest('/docs/guides/auth', { + accept: 'text/html;q=0.5, text/markdown;q=1.0', + }) + expect(middleware(req).headers.get(REWRITE_HEADER)).toBe(GUIDES_MD_REWRITE('auth')) + }) + + it('falls through to HTML when no Accept header is sent', () => { + expect(middleware(makeRequest('/docs/guides/auth')).headers.get(REWRITE_HEADER)).toBeNull() + }) + + it('falls through to HTML for bare Accept: */* (no explicit md preference)', () => { + const req = makeRequest('/docs/guides/auth', { accept: '*/*' }) + expect(middleware(req).headers.get(REWRITE_HEADER)).toBeNull() + }) + + it('does not serve markdown when client explicitly rejects it (q=0)', () => { + const req = makeRequest('/docs/guides/auth', { + accept: 'text/markdown;q=0, text/html;q=1.0', + }) + expect(middleware(req).headers.get(REWRITE_HEADER)).toBeNull() + }) + + it('tolerates OWS in q-params and clamps out-of-range q-values', () => { + // OWS around q: html wins. + const ows = makeRequest('/docs/guides/auth', { + accept: 'text/html ; q = 1.0, text/markdown ; q = 0.5', + }) + expect(middleware(ows).headers.get(REWRITE_HEADER)).toBeNull() + // q=2.0 is out-of-range, falls back to default 1.0; tie -> markdown. + const oor = makeRequest('/docs/guides/auth', { + accept: 'text/html;q=2.0, text/markdown;q=1.0', + }) + expect(middleware(oor).headers.get(REWRITE_HEADER)).toBe(GUIDES_MD_REWRITE('auth')) + }) + + it('returns 406 with Cache-Control: no-store and Vary: Accept when Accept excludes every type', () => { + const req = makeRequest('/docs/guides/auth', { + accept: 'application/x-content-negotiation-probe', + }) + const res = middleware(req) + expect(res.status).toBe(406) + expect(res.headers.get('Cache-Control')).toBe('no-store') + expect(res.headers.get('Vary')).toBe('Accept') + }) + + it('does not 406 for LLM UAs or .md suffix paths even with a probe Accept', () => { + const llm = makeRequest('/docs/guides/auth', { + accept: 'application/x-content-negotiation-probe', + userAgent: 'Claude-User/1.0', + }) + expect(middleware(llm).status).not.toBe(406) + expect(middleware(llm).headers.get(REWRITE_HEADER)).toBe(GUIDES_MD_REWRITE('auth')) + + const md = makeRequest('/docs/guides/auth.md', { + accept: 'application/x-content-negotiation-probe', + }) + expect(middleware(md).status).not.toBe(406) + expect(middleware(md).headers.get(REWRITE_HEADER)).toBe(GUIDES_MD_REWRITE('auth')) + }) + + it('does not 406 on /reference/* (negotiation contract is /guides/* only)', () => { + const req = makeRequest('/docs/reference/javascript/introduction', { + accept: 'application/x-content-negotiation-probe', + }) + expect(middleware(req).status).not.toBe(406) + }) + + it('rewrites for each LLM user agent', () => { + for (const ua of [ + 'Claude-User (claude-code/2.1.119; +https://support.anthropic.com/)', + 'Claude-Web/1.0', + 'Mozilla/5.0 (compatible; ChatGPT-User/1.0)', + 'PerplexityBot/1.0', + ]) { + const req = makeRequest('/docs/guides/auth', { userAgent: ua }) + expect(middleware(req).headers.get(REWRITE_HEADER)).toBe(GUIDES_MD_REWRITE('auth')) + } + }) + + it('LLM UA overrides an Accept header that prefers HTML', () => { + const req = makeRequest('/docs/guides/auth', { + accept: 'text/html;q=1.0, text/markdown;q=0.1', + userAgent: 'Claude-User/1.0', + }) + expect(middleware(req).headers.get(REWRITE_HEADER)).toBe(GUIDES_MD_REWRITE('auth')) + }) + + it('falls through for non-LLM UAs (browsers, training crawlers, substring embeds)', () => { + for (const ua of [ + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36', + 'GPTBot/1.0', + 'ClaudeBot/1.0', + 'CCBot/2.0', + 'chatgpt-userscript/2.0', + 'NotPerplexityBot', + ]) { + const req = makeRequest('/docs/guides/auth', { userAgent: ua }) + expect(middleware(req).headers.get(REWRITE_HEADER)).toBeNull() + } + }) + + it('does not apply LLM UA rewrite to /reference/* (guides-only)', () => { + const req = makeRequest('/docs/reference/javascript/introduction', { + userAgent: 'Claude-User/1.0', + }) + const rewrite = middleware(req).headers.get(REWRITE_HEADER) ?? '' + expect(rewrite).not.toContain('/api/guides-md/') + }) +}) diff --git a/apps/docs/middleware.ts b/apps/docs/middleware.ts index 34cf26138b5..42817c237c7 100644 --- a/apps/docs/middleware.ts +++ b/apps/docs/middleware.ts @@ -1,33 +1,47 @@ +import { clientSdkIds } from '~/content/navigation.references' +import { BASE_PATH } from '~/lib/constants' +import { negotiateMarkdown } from 'common/markdown-negotiation' import { isbot } from 'isbot' import { NextResponse, type NextRequest } from 'next/server' -import { clientSdkIds } from '~/content/navigation.references' -import { BASE_PATH } from '~/lib/constants' - const REFERENCE_PATH = `${BASE_PATH ?? ''}/reference` - const GUIDES_PATH = `${BASE_PATH ?? ''}/guides` export function middleware(request: NextRequest) { const url = new URL(request.url) + const { pathname } = url - const requestsMarkdown = - request.headers.get('Accept')?.includes('text/markdown') || url.pathname.endsWith('.md') + if (pathname.startsWith(GUIDES_PATH + '/')) { + const isMdSuffix = pathname.endsWith('.md') + const slug = pathname.replace(`${GUIDES_PATH}/`, '').replace(/\.md$/, '') + const decision = negotiateMarkdown( + { + acceptHeader: request.headers.get('accept') ?? '', + userAgent: request.headers.get('user-agent') ?? '', + }, + { hasMarkdownVariant: true, isMarkdownSuffix: isMdSuffix } + ) - // Serve pre-generated .md files before the [[...slug]] page route can intercept them - if (url.pathname.startsWith(GUIDES_PATH + '/') && requestsMarkdown) { - const slug = url.pathname.replace(`${GUIDES_PATH}/`, '').replace(/\.md$/, '') - const rewriteUrl = new URL(url) - rewriteUrl.pathname = `${BASE_PATH ?? ''}/api/guides-md/${slug}` - return NextResponse.rewrite(rewriteUrl) + if (decision === 'not-acceptable') { + return new NextResponse('Not Acceptable', { + status: 406, + headers: { 'Cache-Control': 'no-store', Vary: 'Accept' }, + }) + } + + if (decision === 'markdown') { + const rewriteUrl = new URL(url) + rewriteUrl.pathname = `${BASE_PATH ?? ''}/api/guides-md/${slug}` + return NextResponse.rewrite(rewriteUrl) + } } - if (!url.pathname.startsWith(REFERENCE_PATH)) { + if (!pathname.startsWith(REFERENCE_PATH)) { return NextResponse.next() } if (isbot(request.headers.get('user-agent'))) { - let [, lib, maybeVersion, ...slug] = url.pathname.replace(REFERENCE_PATH, '').split('/') + let [, lib, maybeVersion, ...slug] = pathname.replace(REFERENCE_PATH, '').split('/') if (clientSdkIds.includes(lib)) { const version = /v\d+/.test(maybeVersion) ? maybeVersion : undefined @@ -43,7 +57,7 @@ export function middleware(request: NextRequest) { } } - const [, lib, maybeVersion] = url.pathname.replace(REFERENCE_PATH, '').split('/') + const [, lib, maybeVersion] = pathname.replace(REFERENCE_PATH, '').split('/') if (lib === 'cli') { const rewritePath = [REFERENCE_PATH, 'cli'].join('/') diff --git a/apps/www/middleware.ts b/apps/www/middleware.ts index 095fa5f3a67..cef09208638 100644 --- a/apps/www/middleware.ts +++ b/apps/www/middleware.ts @@ -1,56 +1,9 @@ import { stampFirstReferrerCookie } from 'common/first-referrer-cookie' +import { negotiateMarkdown } from 'common/markdown-negotiation' import { NextResponse, type NextRequest } from 'next/server' import { MD_PAGES } from './app/api-v2/md/content.generated' -// Live-fetch agents only. Training crawlers (GPTBot, ClaudeBot, CCBot) are -// governed by robots.txt; serving them content that differs from the HTML -// page risks SEO and cloaking penalties. -const LLM_USER_AGENT = /\bClaude-User\b|\bClaude-Web\b|\bChatGPT-User\b|\bPerplexityBot\b/i - -// Media ranges (RFC 9110 §5.3.2) ordered most to least specific. -const RANGES = ['text/markdown', 'text/html', 'text/*', '*/*'] as const -type Range = (typeof RANGES)[number] - -const Q_PARAM = /^\s*q\s*=\s*([\d.]+)\s*$/i - -function isRange(s: string): s is Range { - return (RANGES as readonly string[]).includes(s) -} - -function parseQ(params: string[]): number { - for (const p of params) { - const q = parseFloat(p.match(Q_PARAM)?.[1] ?? '') - if (Number.isFinite(q) && q >= 0 && q <= 1) return q - } - return 1 -} - -// `markdownExplicit` lets the caller avoid flipping a bare `Accept: */*` to -// markdown — generic clients sending */* aren't expressing a preference. -function parseAccept(header: string) { - const seen = new Map() - - for (const entry of header.toLowerCase().split(',')) { - const [rawType, ...params] = entry.trim().split(';') - const range = rawType.trim() - if (!isRange(range)) continue - seen.set(range, Math.max(seen.get(range) ?? -1, parseQ(params))) - } - - return { - html: seen.get('text/html') ?? seen.get('text/*') ?? seen.get('*/*') ?? 0, - markdown: seen.get('text/markdown') ?? seen.get('text/*') ?? seen.get('*/*') ?? 0, - markdownExplicit: seen.has('text/markdown') || seen.has('text/*'), - } -} - -function shouldServeMarkdown(accept: ReturnType): boolean { - if (accept.markdown === 0) return false - if (accept.markdown > accept.html) return true - return accept.markdown === accept.html && accept.markdownExplicit -} - export function middleware(request: NextRequest) { const { pathname } = request.nextUrl @@ -61,37 +14,28 @@ export function middleware(request: NextRequest) { } } - const acceptHeader = request.headers.get('accept') ?? '' - // Cap UA length before regex test to bound CPU on the edge hot path. - const userAgent = (request.headers.get('user-agent') ?? '').slice(0, 512) - const isLlmAgent = LLM_USER_AGENT.test(userAgent) - const accept = acceptHeader ? parseAccept(acceptHeader) : null - // Strip trailing slash so /auth/ and /auth resolve to the same allowlist // entry — NextURL preserves trailing-slash style on rewrite targets. const slug = (pathname === '/' ? 'homepage' : pathname.slice(1)).replace(/\/$/, '') const isMdEligible = MD_PAGES.has(slug) const isChangelogEntry = slug === 'changelog' || /^changelog\/\d+/.test(slug) - const hasMdVariant = isMdEligible || isChangelogEntry - // 406 when Accept rejects every type we can produce. Skip for LLM UAs - // (always served markdown) and clients with no Accept (browser default). - if ( - hasMdVariant && - !isLlmAgent && - accept !== null && - accept.markdown === 0 && - accept.html === 0 - ) { + const decision = negotiateMarkdown( + { + acceptHeader: request.headers.get('accept') ?? '', + userAgent: request.headers.get('user-agent') ?? '', + }, + { hasMarkdownVariant: isMdEligible || isChangelogEntry } + ) + + if (decision === 'not-acceptable') { return new NextResponse('Not Acceptable', { status: 406, headers: { 'Cache-Control': 'no-store', Vary: 'Accept' }, }) } - const wantsMarkdown = isLlmAgent || (accept !== null && shouldServeMarkdown(accept)) - - if (wantsMarkdown) { + if (decision === 'markdown') { if (isMdEligible) { return NextResponse.rewrite(new URL(`/api-v2/md/${slug}`, request.nextUrl)) } diff --git a/packages/common/markdown-negotiation.test.ts b/packages/common/markdown-negotiation.test.ts new file mode 100644 index 00000000000..cc43407abb9 --- /dev/null +++ b/packages/common/markdown-negotiation.test.ts @@ -0,0 +1,167 @@ +import { describe, expect, it } from 'vitest' + +import { negotiateMarkdown } from './markdown-negotiation' + +const BROWSER_ACCEPT = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' + +describe('negotiateMarkdown', () => { + describe('hasMarkdownVariant gate', () => { + it('passes when the route has no markdown variant, regardless of other signals', () => { + expect( + negotiateMarkdown( + { acceptHeader: 'text/markdown', userAgent: 'Claude-User/1.0' }, + { hasMarkdownVariant: false, isMarkdownSuffix: true } + ) + ).toBe('pass') + }) + }) + + describe('forced markdown', () => { + it('returns markdown for LLM user agents even when Accept rejects everything', () => { + expect( + negotiateMarkdown( + { acceptHeader: 'application/x-content-negotiation-probe', userAgent: 'Claude-User/1.0' }, + { hasMarkdownVariant: true } + ) + ).toBe('markdown') + }) + + it('returns markdown for an explicit .md suffix even with an HTML-only Accept', () => { + expect( + negotiateMarkdown( + { acceptHeader: 'text/html', userAgent: '' }, + { hasMarkdownVariant: true, isMarkdownSuffix: true } + ) + ).toBe('markdown') + }) + + it.each([ + 'Claude-User (claude-code/2.1.119; +https://support.anthropic.com/)', + 'Claude-Web/1.0', + 'Mozilla/5.0 (compatible; ChatGPT-User/1.0)', + 'PerplexityBot/1.0', + ])('treats %s as an LLM agent', (userAgent) => { + expect(negotiateMarkdown({ acceptHeader: '', userAgent }, { hasMarkdownVariant: true })).toBe( + 'markdown' + ) + }) + + it.each([ + 'GPTBot/1.0', + 'ClaudeBot/1.0', + 'CCBot/2.0', + 'chatgpt-userscript/2.0', + 'NotPerplexityBot', + ])('does not treat %s (training crawler / substring embed) as an LLM agent', (userAgent) => { + expect(negotiateMarkdown({ acceptHeader: '', userAgent }, { hasMarkdownVariant: true })).toBe( + 'pass' + ) + }) + + it('caps user-agent length before matching', () => { + const padded = 'x'.repeat(600) + 'Claude-User' + expect( + negotiateMarkdown({ acceptHeader: '', userAgent: padded }, { hasMarkdownVariant: true }) + ).toBe('pass') + }) + }) + + describe('no Accept header', () => { + it('passes (serves HTML) when no Accept header is sent', () => { + expect( + negotiateMarkdown({ acceptHeader: '', userAgent: '' }, { hasMarkdownVariant: true }) + ).toBe('pass') + }) + }) + + describe('406 not-acceptable', () => { + it('returns not-acceptable when Accept excludes every type we serve', () => { + expect( + negotiateMarkdown( + { acceptHeader: 'application/x-content-negotiation-probe', userAgent: '' }, + { hasMarkdownVariant: true } + ) + ).toBe('not-acceptable') + }) + + it('does not 406 for bare */*', () => { + expect( + negotiateMarkdown({ acceptHeader: '*/*', userAgent: '' }, { hasMarkdownVariant: true }) + ).toBe('pass') + }) + }) + + describe('q-value negotiation', () => { + it('serves HTML for browser-style Accept', () => { + expect( + negotiateMarkdown( + { acceptHeader: BROWSER_ACCEPT, userAgent: '' }, + { hasMarkdownVariant: true } + ) + ).toBe('pass') + }) + + it('serves markdown when explicitly requested', () => { + expect( + negotiateMarkdown( + { acceptHeader: 'text/markdown', userAgent: '' }, + { hasMarkdownVariant: true } + ) + ).toBe('markdown') + }) + + it('serves markdown when its q-value beats html', () => { + expect( + negotiateMarkdown( + { acceptHeader: 'text/html;q=0.5, text/markdown;q=1.0', userAgent: '' }, + { hasMarkdownVariant: true } + ) + ).toBe('markdown') + }) + + it('serves HTML when its q-value beats markdown', () => { + expect( + negotiateMarkdown( + { acceptHeader: 'text/html;q=1.0, text/markdown;q=0.5', userAgent: '' }, + { hasMarkdownVariant: true } + ) + ).toBe('pass') + }) + + it('breaks an explicit md/html tie toward markdown', () => { + expect( + negotiateMarkdown( + { acceptHeader: 'text/markdown, text/html, */*', userAgent: '' }, + { hasMarkdownVariant: true } + ) + ).toBe('markdown') + }) + + it('does not serve markdown when the client rejects it (q=0)', () => { + expect( + negotiateMarkdown( + { acceptHeader: 'text/markdown;q=0, text/html;q=1.0', userAgent: '' }, + { hasMarkdownVariant: true } + ) + ).toBe('pass') + }) + + it('tolerates OWS around the q parameter (RFC 9110)', () => { + expect( + negotiateMarkdown( + { acceptHeader: 'text/html ; q = 1.0, text/markdown ; q = 0.5', userAgent: '' }, + { hasMarkdownVariant: true } + ) + ).toBe('pass') + }) + + it('ignores out-of-range q-values (falls back to 1.0; tie -> markdown)', () => { + expect( + negotiateMarkdown( + { acceptHeader: 'text/html;q=2.0, text/markdown;q=1.0', userAgent: '' }, + { hasMarkdownVariant: true } + ) + ).toBe('markdown') + }) + }) +}) diff --git a/packages/common/markdown-negotiation.ts b/packages/common/markdown-negotiation.ts new file mode 100644 index 00000000000..28f8416815a --- /dev/null +++ b/packages/common/markdown-negotiation.ts @@ -0,0 +1,86 @@ +// Live-fetch agents only. Training crawlers (GPTBot, ClaudeBot, CCBot) are +// governed by robots.txt; serving them content that differs from the HTML +// page risks SEO and cloaking penalties. +const LLM_USER_AGENT = /\bClaude-User\b|\bClaude-Web\b|\bChatGPT-User\b|\bPerplexityBot\b/i + +// Media ranges (RFC 9110 §5.3.2) ordered most to least specific. +const RANGES = ['text/markdown', 'text/html', 'text/*', '*/*'] as const +type Range = (typeof RANGES)[number] + +const Q_PARAM = /^\s*q\s*=\s*([\d.]+)\s*$/i + +// Cap UA length before the regex test to bound CPU on the edge hot path. +const MAX_UA_LENGTH = 512 + +function isRange(s: string): s is Range { + return (RANGES as readonly string[]).includes(s) +} + +function parseQ(params: string[]): number { + for (const p of params) { + const q = parseFloat(p.match(Q_PARAM)?.[1] ?? '') + if (Number.isFinite(q) && q >= 0 && q <= 1) return q + } + return 1 +} + +// `markdownExplicit` lets callers avoid flipping a bare `Accept: */*` to +// markdown — generic clients sending */* aren't expressing a preference. +function parseAccept(header: string) { + const seen = new Map() + + for (const entry of header.toLowerCase().split(',')) { + const [rawType, ...params] = entry.trim().split(';') + const range = rawType.trim() + if (!isRange(range)) continue + seen.set(range, Math.max(seen.get(range) ?? -1, parseQ(params))) + } + + return { + html: seen.get('text/html') ?? seen.get('text/*') ?? seen.get('*/*') ?? 0, + markdown: seen.get('text/markdown') ?? seen.get('text/*') ?? seen.get('*/*') ?? 0, + markdownExplicit: seen.has('text/markdown') || seen.has('text/*'), + } +} + +function shouldServeMarkdown(accept: ReturnType): boolean { + if (accept.markdown === 0) return false + if (accept.markdown > accept.html) return true + return accept.markdown === accept.html && accept.markdownExplicit +} + +export type MarkdownDecision = 'markdown' | 'not-acceptable' | 'pass' + +/** + * Content negotiation for routes that can serve either HTML or markdown. + * + * `hasMarkdownVariant` is false for paths with no markdown representation (they + * never negotiate). `isMarkdownSuffix` forces markdown for an explicit `.md` + * request; callers that handle `.md` upstream can leave it false. + */ +export function negotiateMarkdown( + { acceptHeader, userAgent }: { acceptHeader: string; userAgent: string }, + { + hasMarkdownVariant, + isMarkdownSuffix = false, + }: { hasMarkdownVariant: boolean; isMarkdownSuffix?: boolean } +): MarkdownDecision { + if (!hasMarkdownVariant) return 'pass' + + // LLM agents and an explicit `.md` request always get markdown. + if (LLM_USER_AGENT.test(userAgent.slice(0, MAX_UA_LENGTH)) || isMarkdownSuffix) { + return 'markdown' + } + + // No Accept header = browser/default client: serve HTML, never 406. + if (!acceptHeader) return 'pass' + + const accept = parseAccept(acceptHeader) + + // 406 when Accept rejects every type this route can produce. Only reached for + // non-LLM, non-`.md` clients that sent an Accept header (guards above), so a + // deliberate `Accept: application/json` gets a clean 406 instead of HTML. + if (accept.markdown === 0 && accept.html === 0) return 'not-acceptable' + + return shouldServeMarkdown(accept) ? 'markdown' : 'pass' +} From c4da35cc9c61dede012f60b18edd18a3ea6ab4c6 Mon Sep 17 00:00:00 2001 From: Mrinal Paliwal Date: Tue, 9 Jun 2026 15:30:55 +0530 Subject: [PATCH 044/134] add Mrinal Paliwal to humans.txt (#46760) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Docs update ## What is the current behavior? Mrinal is not in humans.txt ## What is the new behavior? Mrinal is in humans.txt 🎉 ## Additional context N/A ## Summary by CodeRabbit * **Chores** * Updated team information. --- apps/docs/public/humans.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/docs/public/humans.txt b/apps/docs/public/humans.txt index 88c75b2bbd1..7d58c5d83e7 100644 --- a/apps/docs/public/humans.txt +++ b/apps/docs/public/humans.txt @@ -195,6 +195,7 @@ Michal Kleczek Michelle Jubrey Miranda Limonczenko Monica Khoury +Mrinal Paliwal Mykhailo Mischa Lieibenson Natalie Roberge Nick B From 88440f087b1be05191becfa36b28382319d7873b Mon Sep 17 00:00:00 2001 From: Jordi Enric <37541088+jordienr@users.noreply.github.com> Date: Tue, 9 Jun 2026 12:18:52 +0200 Subject: [PATCH 045/134] feat(studio): add test connection button for project log drains (#46720) ## Problem Project log drains had no way for users to verify a destination connection before relying on it. Audit log drains already have a "Test connection" action, and the management API exposes the equivalent endpoint for project log drains (`POST /platform/projects/{ref}/analytics/log-drains/{token}/test`). ## Fix - Add `useTestLogDrainMutation` (`apps/studio/data/log-drains/test-log-drain-mutation.ts`), mirroring `useTestAuditLogDrainMutation`. - Wire the already-present `onTestDrain` action in `LogDrains` to the new mutation, so the "Test connection" item now appears in the project log drains row menu. - On success it shows a confirmation toast; failures surface the API error message. ## Testing - Added `apps/studio/data/log-drains/log-drains.test.tsx` covering the test mutation hitting the project-scoped path. - Manual: open Project Settings -> Log Drains, open a drain's menu, click "Test connection". Closes DEBUG-132 ## Summary by CodeRabbit * **New Features** * Added a test capability for log drain connections. Users can now validate that their log drain configurations are functioning correctly before deployment to ensure proper log collection and data integrity. The system provides immediate confirmation when tests succeed and detailed error messages when issues occur, enabling users to quickly troubleshoot and resolve connectivity problems. --------- Co-authored-by: Claude Opus 4.8 --- .../interfaces/LogDrains/LogDrains.tsx | 12 +++++ .../data/log-drains/log-drains.test.tsx | 33 ++++++++++++++ .../log-drains/test-log-drain-mutation.ts | 45 +++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 apps/studio/data/log-drains/log-drains.test.tsx create mode 100644 apps/studio/data/log-drains/test-log-drain-mutation.ts diff --git a/apps/studio/components/interfaces/LogDrains/LogDrains.tsx b/apps/studio/components/interfaces/LogDrains/LogDrains.tsx index a4bb37db5f2..280ef715b2f 100644 --- a/apps/studio/components/interfaces/LogDrains/LogDrains.tsx +++ b/apps/studio/components/interfaces/LogDrains/LogDrains.tsx @@ -7,6 +7,7 @@ import { LogDrainsEmpty } from './LogDrainsEmpty' import { LogDrainsList } from './LogDrainsList' import { useDeleteLogDrainMutation } from '@/data/log-drains/delete-log-drain-mutation' import { LogDrainData, useLogDrainsQuery } from '@/data/log-drains/log-drains-query' +import { useTestLogDrainMutation } from '@/data/log-drains/test-log-drain-mutation' import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements' import { useTrack } from '@/lib/telemetry/track' @@ -35,6 +36,12 @@ export function LogDrains({ }, }) + const { mutate: testLogDrain } = useTestLogDrainMutation({ + onSuccess: () => { + toast.success('Log drain connection test succeeded') + }, + }) + if (isLoadingEntitlement) { return (
@@ -61,6 +68,11 @@ export function LogDrains({ track('log_drain_removed', { destination: drain.type }) } }} + onTestDrain={(drain) => { + if (ref) { + testLogDrain({ token: drain.token, projectRef: ref }) + } + }} /> ) } diff --git a/apps/studio/data/log-drains/log-drains.test.tsx b/apps/studio/data/log-drains/log-drains.test.tsx new file mode 100644 index 00000000000..765d527a0f5 --- /dev/null +++ b/apps/studio/data/log-drains/log-drains.test.tsx @@ -0,0 +1,33 @@ +import { waitFor } from '@testing-library/react' +import { http, HttpResponse } from 'msw' +import { describe, expect, it } from 'vitest' + +import { useTestLogDrainMutation } from './test-log-drain-mutation' +import { API_URL } from '@/lib/constants' +import { customRenderHook } from '@/tests/lib/custom-render' +import { mswServer } from '@/tests/lib/msw' + +const REF = 'my-project' +const BASE = `${API_URL}/platform/projects/:ref/analytics/log-drains` + +describe('project log drain hooks', () => { + it('tests a log drain connection by token at the project-scoped path', async () => { + let receivedRef: string | undefined + let receivedToken: string | undefined + mswServer.use( + http.post(`${BASE}/:token/test`, ({ params }) => { + receivedRef = params.ref as string + receivedToken = params.token as string + return HttpResponse.json({}) + }) + ) + + const { result } = customRenderHook(() => useTestLogDrainMutation()) + + result.current.mutate({ projectRef: REF, token: 'tok-1' }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + expect(receivedRef).toBe(REF) + expect(receivedToken).toBe('tok-1') + }) +}) diff --git a/apps/studio/data/log-drains/test-log-drain-mutation.ts b/apps/studio/data/log-drains/test-log-drain-mutation.ts new file mode 100644 index 00000000000..3e2f3655778 --- /dev/null +++ b/apps/studio/data/log-drains/test-log-drain-mutation.ts @@ -0,0 +1,45 @@ +import { useMutation } from '@tanstack/react-query' +import { toast } from 'sonner' + +import { handleError, post } from '@/data/fetchers' +import type { ResponseError, UseCustomMutationOptions } from '@/types' + +export type LogDrainTestVariables = { + projectRef: string + token: string +} + +export async function testLogDrain({ projectRef, token }: LogDrainTestVariables) { + const { data, error } = await post('/platform/projects/{ref}/analytics/log-drains/{token}/test', { + params: { path: { ref: projectRef, token } }, + }) + + if (error) handleError(error) + return data +} + +type LogDrainTestData = Awaited> + +export const useTestLogDrainMutation = ({ + onSuccess, + onError, + ...options +}: Omit< + UseCustomMutationOptions, + 'mutationFn' +> = {}) => { + return useMutation({ + mutationFn: (vars) => testLogDrain(vars), + async onSuccess(data, variables, context) { + await onSuccess?.(data, variables, context) + }, + async onError(data, variables, context) { + if (onError === undefined) { + toast.error(`Failed to test log drain: ${data.message}`) + } else { + onError(data, variables, context) + } + }, + ...options, + }) +} From 40c947ebfbaa77ed1a91d275fadea3c3b171ec6b Mon Sep 17 00:00:00 2001 From: Ivan Vasilov Date: Tue, 9 Jun 2026 13:30:13 +0300 Subject: [PATCH 046/134] fix: Handle non existant columns when sorting tables (#46741) When a user has sorted by some column in the Table Editor and the column is deleted, the sort data is wrong so it causes issues. In the general view in the Table Editor, the error is handled by removing the sort key when a specific error is detected but it can still happen in ForeignRowSelector. To test: 1. Have 2 tables with references between them. 2. In the `sessionStorage`, under the `supabase_grid-` key, update the sort key to a non-existant column for a table. 3. Try to open the `ForeignRowSelector` for that table by clicking on a cell in the referencing column. ## Summary by CodeRabbit * **Bug Fixes** * Sorting now validates referenced columns and ignores invalid sort entries. * Local sort restoration and UI sort application now derive sorts from the original table context for more consistent behavior across editors and popovers. * Prefetch logic uses the resolved table context when falling back to saved sorts. * **Tests** * Added cases for malformed and out-of-scope sort parameters to prevent regressions. --- .../components/grid/SupabaseGrid.utils.ts | 10 ++++++++-- .../components/header/sort/SortPopover.tsx | 5 ++--- .../components/grid/hooks/useTableSort.ts | 15 +++++---------- .../ForeignRowSelector/ForeignRowSelector.tsx | 7 ++++--- .../prefetchers/project.$ref.editor.$id.tsx | 5 +---- .../tests/components/Grid/Grid.utils.test.ts | 19 +++++++++++++++++-- 6 files changed, 37 insertions(+), 24 deletions(-) diff --git a/apps/studio/components/grid/SupabaseGrid.utils.ts b/apps/studio/components/grid/SupabaseGrid.utils.ts index 200fd880e88..2e9fcca862f 100644 --- a/apps/studio/components/grid/SupabaseGrid.utils.ts +++ b/apps/studio/components/grid/SupabaseGrid.utils.ts @@ -24,14 +24,20 @@ import { BASE_PATH } from '@/lib/constants' import { eventMatchesAnyShortcut } from '@/state/shortcuts/matchEvent' import { tableEditorRegistry } from '@/state/shortcuts/registry/table-editor' -export function formatSortURLParams(tableName: string, sort?: string[]): Sort[] { +export function formatSortURLParams( + // Should match the Entity type. + table: { name: string; columns: { name: string }[] }, + sort?: string[] +): Sort[] { if (Array.isArray(sort)) { return compact( sort.map((s) => { const [column, order] = s.split(':') // Reject any possible malformed sort param if (!column || !order) return undefined - else return { table: tableName, column, ascending: order === 'asc' } + // if the sort column name doesn't exist in the table, reject it as well to avoid confusion + if (table.columns.find((c) => c.name === column) === undefined) return undefined + else return { table: table.name, column, ascending: order === 'asc' } }) ) } diff --git a/apps/studio/components/grid/components/header/sort/SortPopover.tsx b/apps/studio/components/grid/components/header/sort/SortPopover.tsx index 53a344f753d..9562718d236 100644 --- a/apps/studio/components/grid/components/header/sort/SortPopover.tsx +++ b/apps/studio/components/grid/components/header/sort/SortPopover.tsx @@ -13,12 +13,11 @@ export const SortPopover = ({ tableQueriesEnabled }: SortPopoverProps) => { const { urlSorts, onApplySorts } = useTableSort() const snap = useTableEditorTableStateSnapshot() - const tableName = snap.table?.name || '' // Convert string[] to Sort[] const sorts = useMemo(() => { - return tableName && urlSorts ? formatSortURLParams(tableName, urlSorts) : [] - }, [tableName, urlSorts]) + return snap.originalTable && urlSorts ? formatSortURLParams(snap.originalTable, urlSorts) : [] + }, [snap.originalTable, urlSorts]) return ( snap.table?.name || '', [snap]) const sorts = useMemo(() => { - return formatSortURLParams(tableName, urlSorts) - }, [tableName, urlSorts]) + if (!snap.originalTable) return [] + return formatSortURLParams(snap.originalTable, urlSorts) + }, [snap.originalTable, urlSorts]) const onApplySorts = useCallback( (appliedSorts: Sort[]) => { - if (!tableName) { - return console.warn( - '[useTableSort] Table name missing in callback, cannot apply sort correctly.' - ) - } - - const sortsWithTable = appliedSorts.map((sort) => ({ ...sort, table: tableName })) + const sortsWithTable = appliedSorts.map((sort) => ({ ...sort })) const newUrlSorts = sortsToUrlParams(sortsWithTable) setParams((prevParams) => ({ ...prevParams, sort: newUrlSorts })) }, - [snap, setParams] + [setParams] ) /** diff --git a/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/ForeignRowSelector/ForeignRowSelector.tsx b/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/ForeignRowSelector/ForeignRowSelector.tsx index a1776cba958..5a009f0a748 100644 --- a/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/ForeignRowSelector/ForeignRowSelector.tsx +++ b/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/ForeignRowSelector/ForeignRowSelector.tsx @@ -123,12 +123,13 @@ export const ForeignRowSelector = ({ // Load sorts from local storage useEffect(() => { - if (!project?.ref || !table?.name || !table?.schema) return + if (!project?.ref || !table) return try { const savedState = loadTableEditorStateFromLocalStorage(project.ref, table.id) const urlSorts = savedState?.sorts ?? [] - const parsedSorts = formatSortURLParams(table.name, urlSorts) + const parsedSorts = formatSortURLParams(table, urlSorts) + if (parsedSorts.length > 0) { setFiltersAndSorts((prev) => ({ ...prev, sort: parsedSorts })) } @@ -137,7 +138,7 @@ export const ForeignRowSelector = ({ } finally { setShouldSaveSorts(true) } - }, [project?.ref, table?.schema, table?.name, table?.id]) + }, [project?.ref, table]) // Persist sorts to local storage useEffect(() => { diff --git a/apps/studio/data/prefetchers/project.$ref.editor.$id.tsx b/apps/studio/data/prefetchers/project.$ref.editor.$id.tsx index 1fc93b80c9c..0aeb780eefb 100644 --- a/apps/studio/data/prefetchers/project.$ref.editor.$id.tsx +++ b/apps/studio/data/prefetchers/project.$ref.editor.$id.tsx @@ -7,7 +7,6 @@ import { formatFilterURLParams, formatSortURLParams, loadTableEditorStateFromLocalStorage, - parseSupaTable, } from '@/components/grid/SupabaseGrid.utils' import { Filter, Sort } from '@/components/grid/types' import { useConnectionStringForReadOps } from '@/data/read-replicas/replicas-query' @@ -45,8 +44,6 @@ export function prefetchEditorTablePage({ id, }).then((entity) => { if (entity) { - const supaTable = parseSupaTable(entity) - const { sorts: localSorts = [], filters: localFilters = [] } = loadTableEditorStateFromLocalStorage(projectRef, entity.id) ?? {} @@ -55,7 +52,7 @@ export function prefetchEditorTablePage({ connectionString, readReplicaIdentifier, tableId: id, - sorts: sorts ?? formatSortURLParams(supaTable.name, localSorts), + sorts: sorts ?? formatSortURLParams(entity, localSorts), filters: filters ?? formatFilterURLParams(localFilters), page: 1, limit: TABLE_EDITOR_DEFAULT_ROWS_PER_PAGE, diff --git a/apps/studio/tests/components/Grid/Grid.utils.test.ts b/apps/studio/tests/components/Grid/Grid.utils.test.ts index e91b17b4bdc..2801a54cfae 100644 --- a/apps/studio/tests/components/Grid/Grid.utils.test.ts +++ b/apps/studio/tests/components/Grid/Grid.utils.test.ts @@ -23,7 +23,10 @@ vi.mock('sonner', () => ({ describe('SupabaseGrid.utils: formatSortURLParams', () => { test('should return an array of sort options based on URL params', () => { const mockInput = ['id:asc', 'name:desc'] - const output = formatSortURLParams('fakeTable', mockInput) + const output = formatSortURLParams( + { name: 'fakeTable', columns: [{ name: 'id' }, { name: 'name' }] }, + mockInput + ) expect(output).toStrictEqual([ { table: 'fakeTable', column: 'id', ascending: true }, { table: 'fakeTable', column: 'name', ascending: false }, @@ -31,7 +34,10 @@ describe('SupabaseGrid.utils: formatSortURLParams', () => { }) test('should reject any malformed sort options based on URL params', () => { const mockInput = ['id', 'name:asc', ':asc'] - const output = formatSortURLParams('fakeTable', mockInput) + const output = formatSortURLParams( + { name: 'fakeTable', columns: [{ name: 'name' }] }, + mockInput + ) expect(output).toStrictEqual([ { table: 'fakeTable', @@ -40,6 +46,15 @@ describe('SupabaseGrid.utils: formatSortURLParams', () => { }, ]) }) + + test('should reject any sort options with non-existent columns based on URL params', () => { + const mockInput = ['name2:asc'] + const output = formatSortURLParams( + { name: 'fakeTable', columns: [{ name: 'name' }] }, + mockInput + ) + expect(output).toStrictEqual([]) + }) }) // Filter URL syntax: `column:operatorAbbreviation:value` From c71313538481bea5aa75921fe0efc5657ebf5bd7 Mon Sep 17 00:00:00 2001 From: Francesco Sansalvadore Date: Tue, 9 Jun 2026 12:34:20 +0200 Subject: [PATCH 047/134] fix(studio): wrappers install state + one-click install (#46697) - fix install badge state in wrappers detail page - add "Install" button in top action bar - "Install wrapper" if required extensions _aren't_ installed - "Add new wrapper" if required extensions _are_ installed - make wrappers "one-click install" by - showing the required extensions in the CreateWrappersSheet - and automatically installing them on wrapper submission Only available behind `isMarketplaceEnabled` flag at the moment. https://github.com/user-attachments/assets/38f5549d-938e-4e2f-a723-53b9a028e9dc --- .../Landing/useIntegrationDetail.ts | 55 +++- .../Landing/useIntegrationDetail.utils.ts | 65 +++++ .../Marketplace/MarketplaceDetail.tsx | 35 ++- .../Wrappers/AddWrapperButton.tsx | 52 ++++ .../Wrappers/CreateWrapperSheet.tsx | 129 +++++++-- .../Wrappers/Wrappers.utils.test.ts | 81 ++++++ .../Integrations/Wrappers/Wrappers.utils.ts | 27 ++ .../Integrations/Wrappers/WrappersTab.tsx | 43 +-- .../useIntegrationDetail.utils.test.ts | 266 ++++++++++++++++++ 9 files changed, 665 insertions(+), 88 deletions(-) create mode 100644 apps/studio/components/interfaces/Integrations/Landing/useIntegrationDetail.utils.ts create mode 100644 apps/studio/components/interfaces/Integrations/Wrappers/AddWrapperButton.tsx create mode 100644 apps/studio/tests/components/Integrations/Landing/useIntegrationDetail.utils.test.ts diff --git a/apps/studio/components/interfaces/Integrations/Landing/useIntegrationDetail.ts b/apps/studio/components/interfaces/Integrations/Landing/useIntegrationDetail.ts index 2edaa1804a1..f9d8e5cb46d 100644 --- a/apps/studio/components/interfaces/Integrations/Landing/useIntegrationDetail.ts +++ b/apps/studio/components/interfaces/Integrations/Landing/useIntegrationDetail.ts @@ -4,6 +4,13 @@ import { useEffect, useMemo } from 'react' import { useAvailableIntegrations } from './useAvailableIntegrations' import { useInstalledIntegrations } from './useInstalledIntegrations' +import { + areRequiredExtensionsInstalledFor, + getFilteredNavItems, + getInstallActionType, + type InstallActionType, +} from './useIntegrationDetail.utils' +import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { useDatabaseExtensionsQuery } from '@/data/database-extensions/database-extensions-query' import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' @@ -19,6 +26,7 @@ export const useIntegrationDetail = () => { const { ref, id, pageId, childId } = useParams() const { integrationsWrappers } = useIsFeatureEnabled(['integrations:wrappers']) + const isMarketplaceEnabled = useIsMarketplaceEnabled() const { data: project } = useSelectedProjectQuery() const { data: extensions } = useDatabaseExtensionsQuery({ @@ -36,21 +44,23 @@ export const useIntegrationDetail = () => { [installedIntegrations, id] ) - const installableExtensions = (extensions ?? []).filter((ext) => - (integration?.requiredExtensions ?? []).includes(ext.name) + const isInstalled = !!integration && !!installation + + const areRequiredExtensionsInstalled = useMemo( + () => areRequiredExtensionsInstalledFor(integration, extensions), + [integration, extensions] ) - const extensionsInstalled = installableExtensions.every((x) => x.installed_version) - // installedIntegrations doesn't return wrappers unless there's a wrapper created - const isInstalled = - !!integration && (!!installation || (integration.type === 'wrapper' && extensionsInstalled)) - - const navItems = useMemo(() => { - if (!integration?.navigation) return [] - return isInstalled - ? integration.navigation - : integration.navigation.filter((nav) => nav.route === 'overview') - }, [integration, isInstalled]) + const navItems = useMemo( + () => + getFilteredNavItems({ + integration, + isInstalled, + isMarketplaceEnabled, + areRequiredExtensionsInstalled, + }), + [integration, isInstalled, isMarketplaceEnabled, areRequiredExtensionsInstalled] + ) const activeRoute = pageId ?? 'overview' @@ -77,6 +87,22 @@ export const useIntegrationDetail = () => { [integration, id, pageId, childId] ) + const wrappersTabHref = useMemo( + () => tabs.find((tab) => tab.href.endsWith('/wrappers'))?.href, + [tabs] + ) + + const installActionType: InstallActionType = useMemo( + () => + getInstallActionType({ + integration, + isMarketplaceEnabled, + areRequiredExtensionsInstalled, + isInstalled, + }), + [integration, isMarketplaceEnabled, areRequiredExtensionsInstalled, isInstalled] + ) + const isReady = !!router?.isReady const isWrapperBlocked = !integrationsWrappers && !!id?.endsWith('_wrapper') @@ -115,6 +141,9 @@ export const useIntegrationDetail = () => { integration, installation, isInstalled, + areRequiredExtensionsInstalled, + installActionType, + wrappersTabHref, isAvailableLoading, isInstalledLoading, Component, diff --git a/apps/studio/components/interfaces/Integrations/Landing/useIntegrationDetail.utils.ts b/apps/studio/components/interfaces/Integrations/Landing/useIntegrationDetail.utils.ts new file mode 100644 index 00000000000..a21552f9ad6 --- /dev/null +++ b/apps/studio/components/interfaces/Integrations/Landing/useIntegrationDetail.utils.ts @@ -0,0 +1,65 @@ +import type { IntegrationDefinition, Navigation } from './Integrations.constants' + +export type InstallActionType = 'oauth' | 'add-wrapper' | 'installed' | 'install-sheet' | null + +export type DatabaseExtension = { + name: string + installed_version: string | null +} + +/** + * Returns whether all required extensions for an integration are enabled in the database. + */ +export function areRequiredExtensionsInstalledFor( + integration: IntegrationDefinition | undefined, + extensions: DatabaseExtension[] | undefined +): boolean { + if (!integration?.requiredExtensions?.length || !extensions) return false + return integration.requiredExtensions.every( + (name) => !!extensions.find((ext) => ext.name === name)?.installed_version + ) +} + +/** + * Returns the filtered navigation items for an integration based on install / feature-flag state. + * If the marketplace flag is off, only expose the Wrappers tab once extensions are installed + */ +export function getFilteredNavItems({ + integration, + isInstalled, + isMarketplaceEnabled, + areRequiredExtensionsInstalled, +}: { + integration: IntegrationDefinition | undefined + isInstalled: boolean + isMarketplaceEnabled: boolean + areRequiredExtensionsInstalled: boolean +}): Navigation[] { + if (!integration?.navigation) return [] + if (isInstalled || integration.type !== 'wrapper') return integration.navigation + if (isMarketplaceEnabled || areRequiredExtensionsInstalled) return integration.navigation + return integration.navigation.filter((nav) => nav.route !== 'wrappers') +} + +/** + * Returns which install action type to render for an integration. + */ +export function getInstallActionType({ + integration, + isMarketplaceEnabled, + areRequiredExtensionsInstalled, + isInstalled, +}: { + integration: IntegrationDefinition | undefined + isMarketplaceEnabled: boolean + areRequiredExtensionsInstalled: boolean + isInstalled: boolean +}): InstallActionType { + if (!integration) return null + if (integration.type === 'oauth') return 'oauth' + if (integration.type === 'wrapper' && (isMarketplaceEnabled || areRequiredExtensionsInstalled)) { + return 'add-wrapper' + } + if (isInstalled) return 'installed' + return 'install-sheet' +} diff --git a/apps/studio/components/interfaces/Integrations/Marketplace/MarketplaceDetail.tsx b/apps/studio/components/interfaces/Integrations/Marketplace/MarketplaceDetail.tsx index 0562b10799e..df2ff449db8 100644 --- a/apps/studio/components/interfaces/Integrations/Marketplace/MarketplaceDetail.tsx +++ b/apps/studio/components/interfaces/Integrations/Marketplace/MarketplaceDetail.tsx @@ -1,4 +1,5 @@ import { ArrowUpRight, BookOpen } from 'lucide-react' +import { useRouter } from 'next/router' import { Button, cn } from 'ui' import { GenericSkeletonLoader, ShimmeringLoader } from 'ui-patterns' import { Admonition } from 'ui-patterns/admonition' @@ -10,11 +11,13 @@ import { IntegrationDetailTabShortcuts } from '@/components/interfaces/Integrati import { InstallIntegrationSheet } from '@/components/interfaces/Integrations/Integration/IntegrationOverviewTabV2/InstallIntegrationSheet/InstallIntegrationSheet' import { InstallOAuthIntegrationButton } from '@/components/interfaces/Integrations/Integration/IntegrationOverviewTabV2/InstallIntegrationSheet/InstallOAuthIntegrationButton' import { useIntegrationDetail } from '@/components/interfaces/Integrations/Landing/useIntegrationDetail' +import { AddWrapperButton } from '@/components/interfaces/Integrations/Wrappers/AddWrapperButton' import { UnknownInterface } from '@/components/ui/UnknownInterface' export const centeredContentClass = 'mx-auto w-full max-w-6xl px-6 xl:px-10' export const MarketplaceDetail = () => { + const router = useRouter() const { ref, activeRoute, @@ -27,6 +30,8 @@ export const MarketplaceDetail = () => { pageSubTitle, integration, isInstalled, + installActionType, + wrappersTabHref, isAvailableLoading, isInstalledLoading, Component, @@ -66,17 +71,27 @@ export const MarketplaceDetail = () => { } const renderInstallAction = () => { - if (integration.type === 'oauth') { - return + switch (installActionType) { + case 'oauth': + return + case 'add-wrapper': + return ( + { + if (wrappersTabHref) router.push(`${wrappersTabHref}?new=true`) + }} + /> + ) + case 'installed': + return ( + + ) + default: + return } - if (isInstalled) { - return ( - - ) - } - return } // For overview route, get the integration-specific overview component if available diff --git a/apps/studio/components/interfaces/Integrations/Wrappers/AddWrapperButton.tsx b/apps/studio/components/interfaces/Integrations/Wrappers/AddWrapperButton.tsx new file mode 100644 index 00000000000..0b0369d4f61 --- /dev/null +++ b/apps/studio/components/interfaces/Integrations/Wrappers/AddWrapperButton.tsx @@ -0,0 +1,52 @@ +import { PermissionAction } from '@supabase/shared-types/out/constants' +import { useMemo } from 'react' + +import { ButtonTooltip } from '@/components/ui/ButtonTooltip' +import { useDatabaseExtensionsQuery } from '@/data/database-extensions/database-extensions-query' +import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' +import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' + +const WRAPPER_REQUIRED_EXTENSION_NAMES = ['wrappers', 'supabase_vault'] + +interface AddWrapperButtonProps { + type?: 'default' | 'primary' | 'outline' + onClick: () => void +} + +export const AddWrapperButton = ({ type = 'default', onClick }: AddWrapperButtonProps) => { + const { can: canCreateWrapper } = useAsyncCheckPermissions( + PermissionAction.TENANT_SQL_ADMIN_WRITE, + 'wrappers' + ) + + const { data: project } = useSelectedProjectQuery() + const { data: extensions } = useDatabaseExtensionsQuery({ + projectRef: project?.ref, + connectionString: project?.connectionString, + }) + + const needsExtensions = useMemo( + () => + WRAPPER_REQUIRED_EXTENSION_NAMES.some( + (name) => !extensions?.find((ext) => ext.name === name)?.installed_version + ), + [extensions] + ) + + return ( + + {needsExtensions ? 'Install wrapper' : 'Add new wrapper'} + + ) +} diff --git a/apps/studio/components/interfaces/Integrations/Wrappers/CreateWrapperSheet.tsx b/apps/studio/components/interfaces/Integrations/Wrappers/CreateWrapperSheet.tsx index a2baee892c1..e37d9d645a8 100644 --- a/apps/studio/components/interfaces/Integrations/Wrappers/CreateWrapperSheet.tsx +++ b/apps/studio/components/interfaces/Integrations/Wrappers/CreateWrapperSheet.tsx @@ -1,7 +1,7 @@ import { zodResolver } from '@hookform/resolvers/zod' import { useQueryClient } from '@tanstack/react-query' import { Edit, Trash } from 'lucide-react' -import { useEffect, useState } from 'react' +import { useEffect, useMemo, useState } from 'react' import { SubmitHandler, useFieldArray, useForm, useWatch } from 'react-hook-form' import { toast } from 'sonner' import { @@ -18,24 +18,37 @@ import { SheetTitle, WarningIcon, } from 'ui' +import { Admonition } from 'ui-patterns/admonition' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import * as z from 'zod' import InputField from './InputField' import { WrapperMeta } from './Wrappers.types' -import { FormattedWrapperTable, getWrapperCreationFormSchema, NewTable } from './Wrappers.utils' +import { + FormattedWrapperTable, + getRequiredExtensionsToInstall, + getWrapperCreationFormSchema, + hasForeignSchemaSupport, + NewTable, +} from './Wrappers.utils' import WrapperTableEditor from './WrapperTableEditor' +import { useIsMarketplaceEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' +import { getExtensionDefaultSchema } from '@/components/interfaces/Integrations/Integration/IntegrationOverviewTabV2/IntegrationOverviewTabV2.utils' +import { RequiredExtensionsSection } from '@/components/interfaces/Integrations/Integration/RequiredExtensionsSection' +import { useIntegrationDetail } from '@/components/interfaces/Integrations/Landing/useIntegrationDetail' import { FormSection, FormSectionContent, FormSectionLabel, } from '@/components/ui/Forms/FormSection' +import { useDatabaseExtensionEnableMutation } from '@/data/database-extensions/database-extension-enable-mutation' import { useDatabaseExtensionsQuery } from '@/data/database-extensions/database-extensions-query' import { useSchemaCreateMutation } from '@/data/database/schema-create-mutation' import { invalidateSchemasQuery, useSchemasQuery } from '@/data/database/schemas-query' import { useFDWCreateMutation } from '@/data/fdw/fdw-create-mutation' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import { useTrack } from '@/lib/telemetry/track' +import type { ResponseError } from '@/types' const FORM_ID = 'create-wrapper-form' @@ -53,24 +66,27 @@ export const CreateWrapperSheet = ({ onCloseWithConfirmation, }: CreateWrapperSheetProps) => { const queryClient = useQueryClient() + const isMarketplaceEnabled = useIsMarketplaceEnabled() + const { integration } = useIntegrationDetail() const { data: project } = useSelectedProjectQuery() const track = useTrack() - const [selectedTableToEdit, setSelectedTableToEdit] = useState< - FormattedWrapperTable | undefined - >() - const { data: extensions } = useDatabaseExtensionsQuery({ projectRef: project?.ref, connectionString: project?.connectionString, }) + // null while the query is in flight — distinct from [] which means "all installed" + const requiredExtensionsToInstall = useMemo( + () => getRequiredExtensionsToInstall(extensions, integration?.requiredExtensions ?? []), + [extensions, integration?.requiredExtensions] + ) + const wrappersExtension = extensions?.find((ext) => ext.name === 'wrappers') - // The import foreign schema requires a minimum extension version of 0.5.0 - const hasRequiredVersionForeignSchema = wrappersExtension?.installed_version - ? wrappersExtension?.installed_version >= '0.5.0' - : false + const hasRequiredVersionForeignSchema = hasForeignSchemaSupport(wrappersExtension) + const needsExtensions = isMarketplaceEnabled && (requiredExtensionsToInstall?.length ?? 0) > 0 + const isExtensionDataLoading = isMarketplaceEnabled && requiredExtensionsToInstall === null const { data: schemas } = useSchemasQuery({ projectRef: project?.ref!, @@ -113,7 +129,34 @@ export const CreateWrapperSheet = ({ name: 'tables', }) - const { mutateAsync: createSchema, isPending: isCreatingSchema } = useSchemaCreateMutation() + const [selectedTableToEdit, setSelectedTableToEdit] = useState( + undefined + ) + + const { mutateAsync: enableExtension } = useDatabaseExtensionEnableMutation({ onError: () => {} }) + const { mutateAsync: createSchema } = useSchemaCreateMutation({ onError: () => {} }) + const { mutateAsync: createFDW } = useFDWCreateMutation({ onError: () => {} }) + + const installRequiredExtensions = async () => { + if (!project) return + const { ref: projectRef, connectionString } = project + const results = await Promise.allSettled( + (requiredExtensionsToInstall ?? []).map((ext) => { + const schema = getExtensionDefaultSchema(ext) ?? 'extensions' + return enableExtension({ + projectRef, + connectionString, + schema, + name: ext.name, + version: ext.default_version, + cascade: true, + createSchema: false, + }) + }) + ) + const failure = results.find((r) => r.status === 'rejected') + if (failure) throw new Error((failure as PromiseRejectedResult).reason.message) + } const onUpdateTable = (values: FormattedWrapperTable) => { if (values.index !== undefined) { @@ -125,19 +168,6 @@ export const CreateWrapperSheet = ({ setSelectedTableToEdit(undefined) } - const { mutateAsync: createFDW, isPending: isCreatingWrapper } = useFDWCreateMutation({ - onSuccess: () => { - toast.success(`Successfully created ${wrapperMeta?.label} foreign data wrapper`) - - const { tables } = getValues() - const hasNewSchema = (tables as Record[]).some((table) => table.is_new_schema) - if (hasNewSchema) invalidateSchemasQuery(queryClient, project?.ref) - - onClose() - form.reset() - }, - }) - const onSubmit: SubmitHandler = async (values) => { const { mode, tables = [], ...wrapperValues } = values if (mode === 'tables' && tables.length === 0) { @@ -158,13 +188,28 @@ export const CreateWrapperSheet = ({ } } + if (isExtensionDataLoading) return + + const toastId = toast.loading( + needsExtensions + ? `Installing extensions ${(requiredExtensionsToInstall ?? []).map((e) => e.name).join(', ')}…` + : `Creating ${wrapperMeta.label} wrapper…` + ) + try { + if (needsExtensions) { + await installRequiredExtensions() + toast.loading(`Creating ${wrapperMeta.label} wrapper…`, { id: toastId }) + } + if (mode === 'schema') { + toast.loading(`Creating schema "${wrapperValues.target_schema}"…`, { id: toastId }) await createSchema({ projectRef: project?.ref, connectionString: project?.connectionString, name: wrapperValues.target_schema, }) + toast.loading(`Creating ${wrapperMeta.label} wrapper…`, { id: toastId }) } await createFDW({ @@ -182,14 +227,24 @@ export const CreateWrapperSheet = ({ targetSchema: wrapperValues.target_schema, }) + const { tables: formTables } = getValues() + const hasNewSchema = (formTables as Record[]).some((t) => t.is_new_schema) + if (hasNewSchema) invalidateSchemasQuery(queryClient, project?.ref) + track('foreign_data_wrapper_created', { wrapperType: wrapperMeta.label }) + toast.success(`Successfully created ${wrapperMeta.label} foreign data wrapper`, { + id: toastId, + }) + onClose() + form.reset() } catch (error) { - console.error(error) - // The error will be handled by the mutation onError callback (toast.error) + toast.error( + `Failed to create ${wrapperMeta.label} wrapper: ${(error as ResponseError).message}`, + { id: toastId } + ) } } - const isLoading = isCreatingWrapper || isCreatingSchema const wrapper_name = useWatch({ name: 'wrapper_name', control: form.control }) const mode = useWatch({ name: 'mode', control: form.control }) @@ -205,7 +260,19 @@ export const CreateWrapperSheet = ({ Create a {wrapperMeta.label} wrapper -
+
+ {isMarketplaceEnabled && ( +
+ {needsExtensions && ( + + )} + +
+ )} Wrapper Configuration}> Cancel @@ -452,8 +519,8 @@ export const CreateWrapperSheet = ({ type="primary" form={FORM_ID} htmlType="submit" - disabled={isSubmitting || isLoading} - loading={isLoading} + disabled={isSubmitting || isExtensionDataLoading} + loading={isSubmitting} > Create wrapper diff --git a/apps/studio/components/interfaces/Integrations/Wrappers/Wrappers.utils.test.ts b/apps/studio/components/interfaces/Integrations/Wrappers/Wrappers.utils.test.ts index cd1436abd14..e962a44b3a4 100644 --- a/apps/studio/components/interfaces/Integrations/Wrappers/Wrappers.utils.test.ts +++ b/apps/studio/components/interfaces/Integrations/Wrappers/Wrappers.utils.test.ts @@ -4,8 +4,10 @@ import { SUPABASE_TARGET_SCHEMA_OPTION, WRAPPER_HANDLERS } from './Wrappers.cons import { Table } from './Wrappers.types' import { getEditionFormSchema, + getRequiredExtensionsToInstall, getTableFormSchema, getWrapperCreationFormSchema, + hasForeignSchemaSupport, } from './Wrappers.utils' const stripe_wrapper = { @@ -207,3 +209,82 @@ describe('getTableFormSchema', () => { ).toBeDefined() }) }) + +// ─── getRequiredExtensionsToInstall ────────────────────────────────────────── + +describe('getRequiredExtensionsToInstall', () => { + const wrappers = { name: 'wrappers', installed_version: null } + const vault = { name: 'supabase_vault', installed_version: null } + const wrappersInstalled = { name: 'wrappers', installed_version: '0.4.1' } + const vaultInstalled = { name: 'supabase_vault', installed_version: '0.2.8' } + const unrelated = { name: 'pgmq', installed_version: null } + + it('returns null when extensions are undefined (still loading)', () => { + expect(getRequiredExtensionsToInstall(undefined, ['wrappers'])).toBeNull() + }) + + it('returns empty array when required list is empty', () => { + expect(getRequiredExtensionsToInstall([wrappers], [])).toEqual([]) + }) + + it('returns empty array when all required extensions are already installed', () => { + expect( + getRequiredExtensionsToInstall( + [wrappersInstalled, vaultInstalled], + ['wrappers', 'supabase_vault'] + ) + ).toEqual([]) + }) + + it('returns extensions that are required but not installed', () => { + const result = getRequiredExtensionsToInstall( + [wrappers, vaultInstalled], + ['wrappers', 'supabase_vault'] + ) + expect(result).toHaveLength(1) + expect(result![0].name).toBe('wrappers') + }) + + it('returns all required extensions when none are installed', () => { + const result = getRequiredExtensionsToInstall([wrappers, vault], ['wrappers', 'supabase_vault']) + expect(result).toHaveLength(2) + }) + + it('excludes extensions that are not in the required list', () => { + const result = getRequiredExtensionsToInstall([wrappers, unrelated], ['wrappers']) + expect(result).toHaveLength(1) + expect(result![0].name).toBe('wrappers') + }) + + it('returns empty array when extensions list is empty', () => { + expect(getRequiredExtensionsToInstall([], ['wrappers'])).toEqual([]) + }) +}) + +// ─── hasForeignSchemaSupport ────────────────────────────────────────────────── + +describe('hasForeignSchemaSupport', () => { + it('returns false when extension is undefined', () => { + expect(hasForeignSchemaSupport(undefined)).toBe(false) + }) + + it('returns false when installed_version is null (not installed)', () => { + expect(hasForeignSchemaSupport({ installed_version: null })).toBe(false) + }) + + it('returns false for version below 0.5.0', () => { + expect(hasForeignSchemaSupport({ installed_version: '0.4.9' })).toBe(false) + expect(hasForeignSchemaSupport({ installed_version: '0.3.0' })).toBe(false) + expect(hasForeignSchemaSupport({ installed_version: '0.1.0' })).toBe(false) + }) + + it('returns true for exactly version 0.5.0', () => { + expect(hasForeignSchemaSupport({ installed_version: '0.5.0' })).toBe(true) + }) + + it('returns true for version above 0.5.0', () => { + expect(hasForeignSchemaSupport({ installed_version: '0.6.0' })).toBe(true) + expect(hasForeignSchemaSupport({ installed_version: '0.5.1' })).toBe(true) + expect(hasForeignSchemaSupport({ installed_version: '1.0.0' })).toBe(true) + }) +}) diff --git a/apps/studio/components/interfaces/Integrations/Wrappers/Wrappers.utils.ts b/apps/studio/components/interfaces/Integrations/Wrappers/Wrappers.utils.ts index 76834ea78e1..2ff003648c5 100644 --- a/apps/studio/components/interfaces/Integrations/Wrappers/Wrappers.utils.ts +++ b/apps/studio/components/interfaces/Integrations/Wrappers/Wrappers.utils.ts @@ -239,3 +239,30 @@ export function wrapperMetaComparator( export function getWrapperMetaForWrapper(wrapper: FDW | undefined) { return WRAPPERS.find((w) => wrapperMetaComparator(w, wrapper)) } + +/** + * Returns the subset of extensions that are required but not yet installed. + * Returns `null` when the extensions list is still loading (undefined), + * so callers can distinguish "loading" from "nothing to install". + * Generic so the full extension type (including `default_version`) is preserved. + */ +export function getRequiredExtensionsToInstall< + T extends { name: string; installed_version: string | null }, +>(extensions: T[] | undefined, requiredExtensionNames: string[]): T[] | null { + if (extensions === undefined) return null + return extensions.filter( + (ext) => requiredExtensionNames.includes(ext.name) && !ext.installed_version + ) +} + +/** + * Returns true when the wrappers extension is installed at >= 0.5.0, + * which is the minimum version required for IMPORT FOREIGN SCHEMA support. + */ +export function hasForeignSchemaSupport( + wrappersExtension: { installed_version: string | null } | undefined +): boolean { + return wrappersExtension?.installed_version + ? wrappersExtension.installed_version >= '0.5.0' + : false +} diff --git a/apps/studio/components/interfaces/Integrations/Wrappers/WrappersTab.tsx b/apps/studio/components/interfaces/Integrations/Wrappers/WrappersTab.tsx index c52a6df134c..154f8783e73 100644 --- a/apps/studio/components/interfaces/Integrations/Wrappers/WrappersTab.tsx +++ b/apps/studio/components/interfaces/Integrations/Wrappers/WrappersTab.tsx @@ -4,12 +4,12 @@ import { parseAsBoolean, useQueryState } from 'nuqs' import { useCallback, useState } from 'react' import { Sheet, SheetContent } from 'ui' +import { AddWrapperButton } from './AddWrapperButton' import { CreateWrapperSheet } from './CreateWrapperSheet' import { WRAPPERS } from './Wrappers.constants' import { wrapperMetaComparator } from './Wrappers.utils' import { WrapperTable } from './WrapperTable' import { DiscardChangesConfirmationDialog } from '@/components/ui-patterns/Dialogs/DiscardChangesConfirmationDialog' -import { ButtonTooltip } from '@/components/ui/ButtonTooltip' import { DocsButton } from '@/components/ui/DocsButton' import { useFDWsQuery } from '@/data/fdw/fdws-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' @@ -70,44 +70,19 @@ export const WrappersTab = () => {

No {wrapperMeta.label} wrappers have been installed

- setIsCreating(true)} - disabled={!canCreateWrapper} - tooltip={{ - content: { - text: !canCreateWrapper - ? 'You need additional permissions to create a foreign data wrapper' - : undefined, - }, - }} - > - Add new wrapper - + setIsCreating(true)} />
) : ( -
- - setIsCreating(true)} - disabled={!canCreateWrapper} - tooltip={{ - content: { - text: !canCreateWrapper - ? 'You need additional permissions to create a foreign data wrapper' - : undefined, - }, - }} - > - Add new wrapper - -
+ <> +
+ + setIsCreating(true)} /> +
+ + )} - {createdWrappers.length > 0 && } - {wrapperMeta && ( diff --git a/apps/studio/tests/components/Integrations/Landing/useIntegrationDetail.utils.test.ts b/apps/studio/tests/components/Integrations/Landing/useIntegrationDetail.utils.test.ts new file mode 100644 index 00000000000..ef3e01da8ef --- /dev/null +++ b/apps/studio/tests/components/Integrations/Landing/useIntegrationDetail.utils.test.ts @@ -0,0 +1,266 @@ +import { describe, expect, it } from 'vitest' + +import type { IntegrationDefinition } from '@/components/interfaces/Integrations/Landing/Integrations.constants' +import { + areRequiredExtensionsInstalledFor, + getFilteredNavItems, + getInstallActionType, +} from '@/components/interfaces/Integrations/Landing/useIntegrationDetail.utils' + +// Minimal stubs — only fields exercised by the utils +const oauthIntegration = { + id: 'github', + type: 'oauth' as const, + requiredExtensions: [], + navigation: [{ route: 'overview', label: 'Overview' }], +} as unknown as IntegrationDefinition + +const wrapperIntegration = { + id: 'stripe_wrapper', + type: 'wrapper' as const, + requiredExtensions: ['wrappers', 'supabase_vault'], + navigation: [ + { route: 'overview', label: 'Overview' }, + { route: 'wrappers', label: 'Wrappers' }, + ], +} as unknown as IntegrationDefinition + +const extensionIntegration = { + id: 'queues', + type: 'postgres_extension' as const, + requiredExtensions: ['pgmq'], + navigation: [{ route: 'overview', label: 'Overview' }], +} as unknown as IntegrationDefinition + +// ─── areRequiredExtensionsInstalledFor ─────────────────────────────────────── + +describe('areRequiredExtensionsInstalledFor', () => { + it('returns false when integration is undefined', () => { + expect(areRequiredExtensionsInstalledFor(undefined, [])).toBe(false) + }) + + it('returns false when extensions list is undefined', () => { + expect(areRequiredExtensionsInstalledFor(extensionIntegration, undefined)).toBe(false) + }) + + it('returns false when integration has no required extensions', () => { + const noExts = { + ...extensionIntegration, + requiredExtensions: [], + } as unknown as IntegrationDefinition + expect( + areRequiredExtensionsInstalledFor(noExts, [{ name: 'pgmq', installed_version: '1.0' }]) + ).toBe(false) + }) + + it('returns false when a required extension is not installed', () => { + expect( + areRequiredExtensionsInstalledFor(extensionIntegration, [ + { name: 'pgmq', installed_version: null }, + ]) + ).toBe(false) + }) + + it('returns false when a required extension is missing from list entirely', () => { + expect(areRequiredExtensionsInstalledFor(extensionIntegration, [])).toBe(false) + }) + + it('returns true when all required extensions are installed', () => { + expect( + areRequiredExtensionsInstalledFor(extensionIntegration, [ + { name: 'pgmq', installed_version: '1.4.4' }, + ]) + ).toBe(true) + }) + + it('returns true only when every required extension is installed (multiple)', () => { + expect( + areRequiredExtensionsInstalledFor(wrapperIntegration, [ + { name: 'wrappers', installed_version: '0.4.1' }, + { name: 'supabase_vault', installed_version: '0.2.8' }, + ]) + ).toBe(true) + }) + + it('returns false when only some of multiple required extensions are installed', () => { + expect( + areRequiredExtensionsInstalledFor(wrapperIntegration, [ + { name: 'wrappers', installed_version: '0.4.1' }, + { name: 'supabase_vault', installed_version: null }, + ]) + ).toBe(false) + }) +}) + +// ─── getFilteredNavItems ───────────────────────────────────────────────────── + +describe('getFilteredNavItems', () => { + it('returns empty array when integration is undefined', () => { + expect( + getFilteredNavItems({ + integration: undefined, + isInstalled: false, + isMarketplaceEnabled: false, + areRequiredExtensionsInstalled: false, + }) + ).toEqual([]) + }) + + it('returns empty array when integration has no navigation', () => { + const noNav = { + ...wrapperIntegration, + navigation: undefined, + } as unknown as IntegrationDefinition + expect( + getFilteredNavItems({ + integration: noNav, + isInstalled: false, + isMarketplaceEnabled: false, + areRequiredExtensionsInstalled: false, + }) + ).toEqual([]) + }) + + it('returns full navigation for non-wrapper integrations regardless of flags', () => { + const result = getFilteredNavItems({ + integration: extensionIntegration, + isInstalled: false, + isMarketplaceEnabled: false, + areRequiredExtensionsInstalled: false, + }) + expect(result).toEqual(extensionIntegration.navigation) + }) + + it('returns full navigation for installed wrapper integrations', () => { + const result = getFilteredNavItems({ + integration: wrapperIntegration, + isInstalled: true, + isMarketplaceEnabled: false, + areRequiredExtensionsInstalled: false, + }) + expect(result).toEqual(wrapperIntegration.navigation) + }) + + it('hides wrappers tab for uninstalled wrapper when marketplace is off and extensions missing', () => { + const result = getFilteredNavItems({ + integration: wrapperIntegration, + isInstalled: false, + isMarketplaceEnabled: false, + areRequiredExtensionsInstalled: false, + }) + expect(result.some((nav) => nav.route === 'wrappers')).toBe(false) + expect(result.some((nav) => nav.route === 'overview')).toBe(true) + }) + + it('shows wrappers tab when marketplace flag is enabled', () => { + const result = getFilteredNavItems({ + integration: wrapperIntegration, + isInstalled: false, + isMarketplaceEnabled: true, + areRequiredExtensionsInstalled: false, + }) + expect(result).toEqual(wrapperIntegration.navigation) + }) + + it('shows wrappers tab when required extensions are installed', () => { + const result = getFilteredNavItems({ + integration: wrapperIntegration, + isInstalled: false, + isMarketplaceEnabled: false, + areRequiredExtensionsInstalled: true, + }) + expect(result).toEqual(wrapperIntegration.navigation) + }) +}) + +// ─── getInstallActionType ──────────────────────────────────────────────────── + +describe('getInstallActionType', () => { + it('returns null when integration is undefined', () => { + expect( + getInstallActionType({ + integration: undefined, + isMarketplaceEnabled: false, + areRequiredExtensionsInstalled: false, + isInstalled: false, + }) + ).toBeNull() + }) + + it('returns "oauth" for OAuth integrations', () => { + expect( + getInstallActionType({ + integration: oauthIntegration, + isMarketplaceEnabled: false, + areRequiredExtensionsInstalled: false, + isInstalled: false, + }) + ).toBe('oauth') + }) + + it('returns "oauth" for installed OAuth integrations (type check takes priority)', () => { + expect( + getInstallActionType({ + integration: oauthIntegration, + isMarketplaceEnabled: true, + areRequiredExtensionsInstalled: true, + isInstalled: true, + }) + ).toBe('oauth') + }) + + it('returns "add-wrapper" for wrapper when marketplace is enabled', () => { + expect( + getInstallActionType({ + integration: wrapperIntegration, + isMarketplaceEnabled: true, + areRequiredExtensionsInstalled: false, + isInstalled: false, + }) + ).toBe('add-wrapper') + }) + + it('returns "add-wrapper" for wrapper when required extensions are installed', () => { + expect( + getInstallActionType({ + integration: wrapperIntegration, + isMarketplaceEnabled: false, + areRequiredExtensionsInstalled: true, + isInstalled: false, + }) + ).toBe('add-wrapper') + }) + + it('returns "installed" for a non-wrapper installed integration when marketplace is off', () => { + expect( + getInstallActionType({ + integration: extensionIntegration, + isMarketplaceEnabled: false, + areRequiredExtensionsInstalled: false, + isInstalled: true, + }) + ).toBe('installed') + }) + + it('returns "install-sheet" for an uninstalled non-wrapper integration', () => { + expect( + getInstallActionType({ + integration: extensionIntegration, + isMarketplaceEnabled: false, + areRequiredExtensionsInstalled: false, + isInstalled: false, + }) + ).toBe('install-sheet') + }) + + it('returns "install-sheet" for wrapper when marketplace off and extensions missing and not installed', () => { + expect( + getInstallActionType({ + integration: wrapperIntegration, + isMarketplaceEnabled: false, + areRequiredExtensionsInstalled: false, + isInstalled: false, + }) + ).toBe('install-sheet') + }) +}) From fb5cf9edb48cce8fbdae0f31cf01747e1939dacc Mon Sep 17 00:00:00 2001 From: Nicola Ferraro Date: Tue, 9 Jun 2026 12:56:08 +0200 Subject: [PATCH 048/134] Add Nicola Ferraro to humans.txt (#46765) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Docs update ## What is the current behavior? Me missing from the list ## What is the new behavior? I'll be in the list ## Additional context Joined yesterday ## Summary by CodeRabbit * **Chores** * Updated team member information in public documentation. --- apps/docs/public/humans.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/docs/public/humans.txt b/apps/docs/public/humans.txt index 7d58c5d83e7..8ed0ed04de9 100644 --- a/apps/docs/public/humans.txt +++ b/apps/docs/public/humans.txt @@ -201,6 +201,7 @@ Natalie Roberge Nick B Nick Littman Nick Nowlan +Nicola Ferraro Nicolas Nosenzo Noah Moss Nyannyacha From 871e55434b1192f3341e52b1e69995046d6a5131 Mon Sep 17 00:00:00 2001 From: Marcus Weiner Date: Tue, 9 Jun 2026 14:23:08 +0200 Subject: [PATCH 049/134] fix(docs): Delete regional availability details for PrivateLink (#46774) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Docs update ## What is the current behavior? Documenting limited regional availability which is no longer the case ## What is the new behavior? Section about regional availability limits removed ## Additional context Privatelink is now available in `eu-central-2` --- apps/docs/content/guides/platform/privatelink.mdx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/apps/docs/content/guides/platform/privatelink.mdx b/apps/docs/content/guides/platform/privatelink.mdx index f3db55b4819..4e602ed56cc 100644 --- a/apps/docs/content/guides/platform/privatelink.mdx +++ b/apps/docs/content/guides/platform/privatelink.mdx @@ -178,9 +178,3 @@ The PrivateLink endpoint is a layer 3 solution so behaves like a standard Postgr Ready to enhance your database security with PrivateLink? [Contact our Enterprise team](/contact/enterprise) to discuss your requirements and begin the setup process. Our support team will guide you through the configuration and ensure your private database connectivity meets your security and performance requirements. - -## Regional availability - -PrivateLink is not currently available in the following regions: - -- **eu-central-2 (Zurich)** - Expected availability: April 2026 From 19ae3501e64290f2a7ea83823465c4f25e1b1c9a Mon Sep 17 00:00:00 2001 From: Jeremias Menichelli Date: Tue, 9 Jun 2026 14:33:22 +0200 Subject: [PATCH 050/134] fix: Make markdown links absolute (#46773) In this PR: - For preview and production builds, Vercel deployment URL gets prepend in markdown links. --- .../internals/generate-guides-markdown.ts | 6 +- .../internals/generate-reference-markdown.ts | 5 +- apps/docs/internals/internal-links.test.ts | 194 ++++++++++++++++++ apps/docs/internals/internal-links.ts | 39 ++++ 4 files changed, 242 insertions(+), 2 deletions(-) create mode 100644 apps/docs/internals/internal-links.test.ts create mode 100644 apps/docs/internals/internal-links.ts diff --git a/apps/docs/internals/generate-guides-markdown.ts b/apps/docs/internals/generate-guides-markdown.ts index 8fdf3273617..a7be3589be5 100644 --- a/apps/docs/internals/generate-guides-markdown.ts +++ b/apps/docs/internals/generate-guides-markdown.ts @@ -3,6 +3,8 @@ import path from 'node:path' import { globby } from 'globby' import matter from 'gray-matter' +import { getInternalLinkBaseUrl, prefixInternalLinks } from './internal-links' + const PARTIALS_DIR = path.join(process.cwd(), 'content', '_partials') /** @@ -195,6 +197,7 @@ function stripJsxTags(content: string): string { async function generate() { const files = await globby(['content/guides/**/!(_)*.mdx']) + const linkBaseUrl = getInternalLinkBaseUrl() let warnings = 0 await Promise.all( @@ -211,7 +214,8 @@ async function generate() { const withPartials = await inlinePartials(rawContent) const withSteps = convertStepHike(withPartials) const withLinks = convertLinkPanels(withSteps) - const processed = stripJsxTags(withLinks) + const stripped = stripJsxTags(withLinks) + const processed = prefixInternalLinks(stripped, linkBaseUrl) const header = [ data.title ? `# ${data.title}` : '', diff --git a/apps/docs/internals/generate-reference-markdown.ts b/apps/docs/internals/generate-reference-markdown.ts index f216ff89e52..6c3b05997ff 100644 --- a/apps/docs/internals/generate-reference-markdown.ts +++ b/apps/docs/internals/generate-reference-markdown.ts @@ -3,6 +3,8 @@ import path from 'node:path' import matter from 'gray-matter' import yaml from 'js-yaml' +import { getInternalLinkBaseUrl, prefixInternalLinks } from './internal-links' + const GENERATED = path.join(process.cwd(), 'features/docs/generated') const OUT_DIR = path.join(process.cwd(), 'public/markdown/reference') const MDX_ROOT = path.join(process.cwd(), 'docs/ref') @@ -386,6 +388,7 @@ async function generate() { const sharedTypeSpec = await readJson( path.join(process.cwd(), 'content/reference/javascript/v2/typeSpec.json') ) + const linkBaseUrl = getInternalLinkBaseUrl() await Promise.all( REFERENCES.map(async (ref) => { @@ -404,7 +407,7 @@ async function generate() { output = await renderCli(ref) break } - await fs.writeFile(path.join(OUT_DIR, ref.outFile), output) + await fs.writeFile(path.join(OUT_DIR, ref.outFile), prefixInternalLinks(output, linkBaseUrl)) }) ) diff --git a/apps/docs/internals/internal-links.test.ts b/apps/docs/internals/internal-links.test.ts new file mode 100644 index 00000000000..4558e679f71 --- /dev/null +++ b/apps/docs/internals/internal-links.test.ts @@ -0,0 +1,194 @@ +import { afterEach, beforeEach, describe, expect, it } from 'vitest' + +import { getInternalLinkBaseUrl, prefixInternalLinks } from './internal-links' + +describe('getInternalLinkBaseUrl', () => { + const ORIGINAL_ENV = process.env + + beforeEach(() => { + process.env = { ...ORIGINAL_ENV } + delete process.env.VERCEL_ENV + delete process.env.VERCEL_URL + }) + + afterEach(() => { + process.env = ORIGINAL_ENV + }) + + it('returns the production host when VERCEL_ENV=production', () => { + process.env.VERCEL_ENV = 'production' + expect(getInternalLinkBaseUrl()).toBe('https://supabase.com') + }) + + it('production wins even if VERCEL_URL is also set', () => { + process.env.VERCEL_ENV = 'production' + process.env.VERCEL_URL = 'should-be-ignored.vercel.app' + expect(getInternalLinkBaseUrl()).toBe('https://supabase.com') + }) + + it('returns the deployment URL when VERCEL_ENV=preview', () => { + process.env.VERCEL_ENV = 'preview' + process.env.VERCEL_URL = 'supabase-com-abc123.vercel.app' + expect(getInternalLinkBaseUrl()).toBe('https://supabase-com-abc123.vercel.app') + }) + + it('returns empty when preview is set but VERCEL_URL is missing', () => { + process.env.VERCEL_ENV = 'preview' + expect(getInternalLinkBaseUrl()).toBe('') + }) + + it('returns empty when VERCEL_ENV=development', () => { + process.env.VERCEL_ENV = 'development' + process.env.VERCEL_URL = 'localhost-tunnel.vercel.app' + expect(getInternalLinkBaseUrl()).toBe('') + }) + + it('returns empty when VERCEL_ENV is not set (local)', () => { + expect(getInternalLinkBaseUrl()).toBe('') + }) +}) + +describe('prefixInternalLinks', () => { + const BASE = 'https://supabase.com' + + it('returns content unchanged when baseUrl is empty', () => { + const input = 'See [Dashboard](/dashboard/foo).' + expect(prefixInternalLinks(input, '')).toBe(input) + }) + + it('prepends baseUrl to a root-relative link', () => { + expect(prefixInternalLinks('See [Dashboard](/dashboard/foo).', BASE)).toBe( + 'See [Dashboard](https://supabase.com/dashboard/foo).' + ) + }) + + it('rewrites multiple links on the same line', () => { + const input = 'A [one](/a) and [two](/b/c) here.' + expect(prefixInternalLinks(input, BASE)).toBe( + 'A [one](https://supabase.com/a) and [two](https://supabase.com/b/c) here.' + ) + }) + + it('preserves query strings and fragments', () => { + expect(prefixInternalLinks('[link](/foo?bar=1&baz=2#section)', BASE)).toBe( + '[link](https://supabase.com/foo?bar=1&baz=2#section)' + ) + }) + + it('leaves absolute http(s) links alone', () => { + const input = 'See [GitHub](https://github.com/supabase).' + expect(prefixInternalLinks(input, BASE)).toBe(input) + }) + + it('leaves anchor-only links alone', () => { + const input = 'Jump to [section](#installation).' + expect(prefixInternalLinks(input, BASE)).toBe(input) + }) + + it('leaves mailto and other schemes alone', () => { + const input = 'Email [us](mailto:team@example.com) or [call](tel:+1234).' + expect(prefixInternalLinks(input, BASE)).toBe(input) + }) + + it('leaves explicitly relative links (./, ../) alone', () => { + const input = 'See [sibling](./sibling) and [parent](../parent).' + expect(prefixInternalLinks(input, BASE)).toBe(input) + }) + + it('leaves protocol-relative (//host) URLs alone', () => { + const input = 'CDN [asset](//cdn.example.com/img.png).' + expect(prefixInternalLinks(input, BASE)).toBe(input) + }) + + it('does not rewrite image syntax', () => { + const input = 'An image: ![alt text](/static/foo.png).' + expect(prefixInternalLinks(input, BASE)).toBe(input) + }) + + it('rewrites a link adjacent to an image without touching the image', () => { + expect(prefixInternalLinks('![logo](/logo.png) and [home](/dashboard)', BASE)).toBe( + '![logo](/logo.png) and [home](https://supabase.com/dashboard)' + ) + }) + + it('skips links inside fenced code blocks', () => { + const input = [ + 'Before: [yes](/touch-me).', + '', + '```md', + '[ignore me](/leave-alone)', + '```', + '', + 'After: [also yes](/touch-me-too).', + ].join('\n') + + expect(prefixInternalLinks(input, BASE)).toBe( + [ + 'Before: [yes](https://supabase.com/touch-me).', + '', + '```md', + '[ignore me](/leave-alone)', + '```', + '', + 'After: [also yes](https://supabase.com/touch-me-too).', + ].join('\n') + ) + }) + + it('handles multiple fenced code blocks correctly', () => { + const input = [ + '[a](/a)', + '```', + '[skip1](/skip1)', + '```', + '[b](/b)', + '```ts', + '[skip2](/skip2)', + '```', + '[c](/c)', + ].join('\n') + + expect(prefixInternalLinks(input, BASE)).toBe( + [ + '[a](https://supabase.com/a)', + '```', + '[skip1](/skip1)', + '```', + '[b](https://supabase.com/b)', + '```ts', + '[skip2](/skip2)', + '```', + '[c](https://supabase.com/c)', + ].join('\n') + ) + }) + + it('rewrites links with empty text', () => { + expect(prefixInternalLinks('[](/foo)', BASE)).toBe('[](https://supabase.com/foo)') + }) + + it('uses any baseUrl passed in, not just supabase.com', () => { + expect(prefixInternalLinks('[x](/y)', 'https://branch-deploy.vercel.app')).toBe( + '[x](https://branch-deploy.vercel.app/y)' + ) + }) + + it('is a no-op when there are no matching links', () => { + const input = '# Title\n\nJust prose, no links.' + expect(prefixInternalLinks(input, BASE)).toBe(input) + }) + + it('handles an unclosed code fence by leaving the unclosed portion untouched', () => { + // A `split(/(```...```)/)` only pairs complete fences; an unclosed fence + // means everything after it stays in the trailing prose segment. Document + // that behavior rather than promising to parse malformed markdown. + const input = ['[before](/before)', '```', '[inside-unclosed](/inside)'].join('\n') + expect(prefixInternalLinks(input, BASE)).toBe( + [ + '[before](https://supabase.com/before)', + '```', + '[inside-unclosed](https://supabase.com/inside)', + ].join('\n') + ) + }) +}) diff --git a/apps/docs/internals/internal-links.ts b/apps/docs/internals/internal-links.ts new file mode 100644 index 00000000000..5742e007824 --- /dev/null +++ b/apps/docs/internals/internal-links.ts @@ -0,0 +1,39 @@ +/** + * Returns the absolute base URL to prepend to root-relative markdown links + * (e.g. `/dashboard/...`). Empty when no rewrite should happen — typically + * local development, where keeping links relative lets them resolve against + * whatever host the dev server is on. + * + * Resolution order: + * - `VERCEL_ENV=production` → `https://supabase.com` + * - `VERCEL_ENV=preview` → `https://${VERCEL_URL}` + * - anything else → '' + */ +export function getInternalLinkBaseUrl(): string { + const env = process.env.VERCEL_ENV + if (env === 'production') return 'https://supabase.com' + if (env === 'preview' && process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}` + return '' +} + +/** + * Rewrite root-relative markdown links by prepending `baseUrl`: + * `[text](/foo)` → `[text](${baseUrl}/foo)` + * + * Skips fenced code blocks, image syntax (`![alt](...)`), protocol-relative + * URLs (`//host/...`), and non-root-relative targets (`http://`, `mailto:`, + * `#anchor`, `./`, `../`). + */ +export function prefixInternalLinks(content: string, baseUrl: string): string { + if (!baseUrl) return content + const segments = content.split(/(```[\s\S]*?```)/g) + return segments + .map((seg, i) => { + if (i % 2 === 1) return seg + return seg.replace(/(? { + if (url.startsWith('//')) return match + return `${text}(${baseUrl}${url})` + }) + }) + .join('') +} From fc6b42ea1a1d2a27d9712f021ec21a5f57f73521 Mon Sep 17 00:00:00 2001 From: Ali Waseem Date: Tue, 9 Jun 2026 07:17:42 -0600 Subject: [PATCH 051/134] fix: added schema switching shortcut (#46753) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Added a small shortcut to make it easier to switch schemas in the table editor ## Summary by CodeRabbit * **New Features** * Added a keyboard shortcut (S+S) to open the schema selector in the table editor for faster navigation and accessibility. * Schema selector now supports keyboard/shortcut-driven control and tooltip guidance. * Selector automatically closes when a schema is chosen or after creating a new schema. --- .../TableEditorLayout/TableEditorMenu.tsx | 39 ++++++++++++++----- .../state/shortcuts/registry/table-editor.ts | 8 ++++ 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/apps/studio/components/layouts/TableEditorLayout/TableEditorMenu.tsx b/apps/studio/components/layouts/TableEditorLayout/TableEditorMenu.tsx index 3055b2c3a2e..bec5bb3c501 100644 --- a/apps/studio/components/layouts/TableEditorLayout/TableEditorMenu.tsx +++ b/apps/studio/components/layouts/TableEditorLayout/TableEditorMenu.tsx @@ -24,6 +24,7 @@ import { EditorMenuListSkeleton } from '@/components/layouts/TableEditorLayout/E import { ButtonTooltip } from '@/components/ui/ButtonTooltip' import { InfiniteListDefault, LoaderForIconMenuItems } from '@/components/ui/InfiniteList' import SchemaSelector from '@/components/ui/SchemaSelector' +import { ShortcutTooltip } from '@/components/ui/ShortcutTooltip' import { ENTITY_TYPE } from '@/data/entity-types/entity-type-constants' import { useEntityTypesQuery } from '@/data/entity-types/entity-types-infinite-query' import { useTableApiAccessQuery } from '@/data/privileges/table-api-access-query' @@ -33,6 +34,8 @@ import { useLocalStorage } from '@/hooks/misc/useLocalStorage' import { useQuerySchemaState } from '@/hooks/misc/useSchemaQueryState' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import { useIsProtectedSchema } from '@/hooks/useProtectedSchemas' +import { SHORTCUT_IDS } from '@/state/shortcuts/registry' +import { useShortcut } from '@/state/shortcuts/useShortcut' import { useTableEditorStateSnapshot } from '@/state/table-editor' export const TableEditorMenu = () => { @@ -42,6 +45,7 @@ export const TableEditorMenu = () => { const { selectedSchema, setSelectedSchema } = useQuerySchemaState() const [searchText, setSearchText] = useState('') + const [isSchemaDropdownOpen, setIsSchemaDropdownOpen] = useState(false) const [tableToExport, setTableToExport] = useState() const [visibleTypes, setVisibleTypes] = useState(Object.values(ENTITY_TYPE)) const [sort, setSort] = useLocalStorage<'alphabetical' | 'grouped-alphabetical'>( @@ -106,6 +110,10 @@ export const TableEditorMenu = () => { setSelectedSchema(selectedTable.schema) } + useShortcut(SHORTCUT_IDS.TABLE_EDITOR_FOCUS_SCHEMA, () => setIsSchemaDropdownOpen(true), { + registerInCommandMenu: true, + }) + const tableEditorTabsCleanUp = useTableEditorTabsCleanUp() const onSelectExportCLI = useCallback( @@ -151,15 +159,28 @@ export const TableEditorMenu = () => { <>
- { - setSearchText('') - setSelectedSchema(name) - }} - onSelectCreateSchema={() => snap.onAddSchema()} - /> + + { + setSearchText('') + setSelectedSchema(name) + setIsSchemaDropdownOpen(false) + }} + onSelectCreateSchema={() => { + snap.onAddSchema() + setIsSchemaDropdownOpen(false) + }} + open={isSchemaDropdownOpen} + onOpenChange={setIsSchemaDropdownOpen} + /> +
{!isSchemaLocked ? ( diff --git a/apps/studio/state/shortcuts/registry/table-editor.ts b/apps/studio/state/shortcuts/registry/table-editor.ts index 374ef466c74..2c02b97eb52 100644 --- a/apps/studio/state/shortcuts/registry/table-editor.ts +++ b/apps/studio/state/shortcuts/registry/table-editor.ts @@ -19,6 +19,7 @@ export const TABLE_EDITOR_SHORTCUT_IDS = { TABLE_EDITOR_CLEAR_FILTERS: 'table-editor.clear-filters', TABLE_EDITOR_CLEAR_SORT: 'table-editor.clear-sort', TABLE_EDITOR_REFRESH: 'table-editor.refresh', + TABLE_EDITOR_FOCUS_SCHEMA: 'table-editor.focus-schema', } export type TableEditorShortcutId = @@ -151,4 +152,11 @@ export const tableEditorRegistry: RegistryDefinations = { showInSettings: false, options: { ignoreInputs: true }, }, + [TABLE_EDITOR_SHORTCUT_IDS.TABLE_EDITOR_FOCUS_SCHEMA]: { + id: TABLE_EDITOR_SHORTCUT_IDS.TABLE_EDITOR_FOCUS_SCHEMA, + label: 'Focus schema selector', + sequence: ['S', 'S'], + showInSettings: false, + options: { ignoreInputs: true }, + }, } From ff34a6753c41564d46873da7a82bc1e82304b459 Mon Sep 17 00:00:00 2001 From: Gildas Garcia <1122076+djhi@users.noreply.github.com> Date: Tue, 9 Jun 2026 15:30:18 +0200 Subject: [PATCH 052/134] chore: remove unnecessary `` (#46763) ## Problem Since the refactor done in #43900, the `` does not bring much value. ## Solution Remove `PreventNavigationOnUnsavedChanges` and update consumers to leverage `usePreventNavigationOnUnsavedChanges` and `DiscardChangesConfirmationDialog` ## Summary by CodeRabbit * **Refactor** * Improved the architecture of unsaved-changes navigation handling across multiple features. Components now use a more modular hook-based approach for better code organization and consistency. --- .../Auth/EmailTemplates/TemplateEditor.tsx | 14 ++++++++-- .../components/interfaces/Reports/Reports.tsx | 14 ++++++++-- .../PreventNavigationOnUnsavedChanges.tsx | 26 ------------------- .../usePreventNavigationOnUnsavedChanges.ts | 18 ++++++------- .../[ref]/functions/[functionSlug]/code.tsx | 14 ++++++++-- .../pages/project/[ref]/functions/new.tsx | 13 ++++++++-- 6 files changed, 56 insertions(+), 43 deletions(-) delete mode 100644 apps/studio/components/ui-patterns/Dialogs/PreventNavigationOnUnsavedChanges.tsx diff --git a/apps/studio/components/interfaces/Auth/EmailTemplates/TemplateEditor.tsx b/apps/studio/components/interfaces/Auth/EmailTemplates/TemplateEditor.tsx index 51a24452e5e..be691be50fc 100644 --- a/apps/studio/components/interfaces/Auth/EmailTemplates/TemplateEditor.tsx +++ b/apps/studio/components/interfaces/Auth/EmailTemplates/TemplateEditor.tsx @@ -27,7 +27,7 @@ import type { AuthTemplate } from './EmailTemplates.types' import { hasCustomEmailSender } from './EmailTemplates.utils' import { ResetTemplateDialog } from './ResetTemplateDialog' import { SpamValidation } from './SpamValidation' -import { PreventNavigationOnUnsavedChanges } from '@/components/ui-patterns/Dialogs/PreventNavigationOnUnsavedChanges' +import { DiscardChangesConfirmationDialog } from '@/components/ui-patterns/Dialogs/DiscardChangesConfirmationDialog' import { ButtonTooltip } from '@/components/ui/ButtonTooltip' import { CodeEditor } from '@/components/ui/CodeEditor/CodeEditor' import { InlineLink } from '@/components/ui/InlineLink' @@ -37,6 +37,7 @@ import { useAuthConfigQuery } from '@/data/auth/auth-config-query' import { useAuthConfigUpdateMutation } from '@/data/auth/auth-config-update-mutation' import { useValidateSpamMutation, ValidateSpamResponse } from '@/data/auth/validate-spam-mutation' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' +import { usePreventNavigationOnUnsavedChanges } from '@/hooks/ui/usePreventNavigationOnUnsavedChanges' import { DOCS_URL } from '@/lib/constants' interface TemplateEditorProps { @@ -270,6 +271,11 @@ export const TemplateEditor = ({ template, isReadOnly = false }: TemplateEditorP if (!canEdit) setActiveView('preview') }, [canEdit]) + const { handleCancelNavigation, handleConfirmNavigation, shouldConfirmNavigation } = + usePreventNavigationOnUnsavedChanges({ + hasChanges, + }) + return (
@@ -466,7 +472,11 @@ export const TemplateEditor = ({ template, isReadOnly = false }: TemplateEditorP )}
- + ) } diff --git a/apps/studio/components/interfaces/Reports/Reports.tsx b/apps/studio/components/interfaces/Reports/Reports.tsx index ea05dc5a7fe..5f360f319ac 100644 --- a/apps/studio/components/interfaces/Reports/Reports.tsx +++ b/apps/studio/components/interfaces/Reports/Reports.tsx @@ -12,7 +12,7 @@ import { ChartConfig } from '../SQLEditor/UtilityPanel/ChartConfig' import { GridResize } from './GridResize' import { MetricOptions } from './MetricOptions' import { LAYOUT_COLUMN_COUNT } from './Reports.constants' -import { PreventNavigationOnUnsavedChanges } from '@/components/ui-patterns/Dialogs/PreventNavigationOnUnsavedChanges' +import { DiscardChangesConfirmationDialog } from '@/components/ui-patterns/Dialogs/DiscardChangesConfirmationDialog' import { ButtonTooltip } from '@/components/ui/ButtonTooltip' import { DatabaseSelector } from '@/components/ui/DatabaseSelector' import { DateRangePicker } from '@/components/ui/DateRangePicker' @@ -27,6 +27,7 @@ import { } from '@/data/content/content-upsert-mutation' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' +import { usePreventNavigationOnUnsavedChanges } from '@/hooks/ui/usePreventNavigationOnUnsavedChanges' import { Metric, TIME_PERIODS_REPORTS } from '@/lib/constants/metrics' import { uuidv4 } from '@/lib/helpers' import { useProfile } from '@/lib/profile' @@ -352,6 +353,11 @@ const Reports = () => { checkEditState() }, [config]) + const { handleCancelNavigation, handleConfirmNavigation, shouldConfirmNavigation } = + usePreventNavigationOnUnsavedChanges({ + hasChanges: hasEdits, + }) + if (isLoading || isLoadingPermissions) { return } @@ -491,7 +497,11 @@ const Reports = () => {
)}
- + ) } diff --git a/apps/studio/components/ui-patterns/Dialogs/PreventNavigationOnUnsavedChanges.tsx b/apps/studio/components/ui-patterns/Dialogs/PreventNavigationOnUnsavedChanges.tsx deleted file mode 100644 index 3ea9eb30008..00000000000 --- a/apps/studio/components/ui-patterns/Dialogs/PreventNavigationOnUnsavedChanges.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { - DiscardChangesConfirmationDialog, - type DiscardChangesConfirmationDialogProps, -} from './DiscardChangesConfirmationDialog' -import { usePreventNavigationOnUnsavedChanges } from '@/hooks/ui/usePreventNavigationOnUnsavedChanges' - -export const PreventNavigationOnUnsavedChanges = ({ - hasChanges, - ...props -}: { hasChanges: boolean } & Omit< - DiscardChangesConfirmationDialogProps, - 'visible' | 'onClose' | 'onCancel' ->) => { - const { handleCancel, handleConfirm, shouldConfirm } = usePreventNavigationOnUnsavedChanges({ - hasChanges, - }) - - return ( - - ) -} diff --git a/apps/studio/hooks/ui/usePreventNavigationOnUnsavedChanges.ts b/apps/studio/hooks/ui/usePreventNavigationOnUnsavedChanges.ts index c80ac3fb2fd..bc8cf663fa5 100644 --- a/apps/studio/hooks/ui/usePreventNavigationOnUnsavedChanges.ts +++ b/apps/studio/hooks/ui/usePreventNavigationOnUnsavedChanges.ts @@ -15,16 +15,16 @@ interface UsePreventNavigationOnUnsavedChangesReturn { /* * Cancel the navigation and keep the changes */ - handleCancel: () => void + handleCancelNavigation: () => void /* * Confirm the navigation and lose the changes */ - handleConfirm: () => void + handleConfirmNavigation: () => void /* * Boolean indicating whether UI to request users confirmation for the navigation should be * displayed */ - shouldConfirm: boolean + shouldConfirmNavigation: boolean } /* @@ -64,11 +64,11 @@ export const usePreventNavigationOnUnsavedChanges = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [confirmNavigate, hasChanges]) - const handleCancel = useCallback(() => { + const handleCancelNavigation = useCallback(() => { setNavigateUrl(undefined) }, []) - const handleConfirm = useCallback(() => { + const handleConfirmNavigation = useCallback(() => { setConfirmNavigate(true) let urlToNavigate = navigateUrl ?? '/' if (BASE_PATH && urlToNavigate.startsWith(BASE_PATH)) { @@ -81,10 +81,10 @@ export const usePreventNavigationOnUnsavedChanges = ({ return useMemo( () => ({ - handleCancel, - handleConfirm, - shouldConfirm: !!navigateUrl, + handleCancelNavigation, + handleConfirmNavigation, + shouldConfirmNavigation: !!navigateUrl, }), - [navigateUrl, handleCancel, handleConfirm] + [navigateUrl, handleCancelNavigation, handleConfirmNavigation] ) } diff --git a/apps/studio/pages/project/[ref]/functions/[functionSlug]/code.tsx b/apps/studio/pages/project/[ref]/functions/[functionSlug]/code.tsx index a5a2c56e354..416583a36f8 100644 --- a/apps/studio/pages/project/[ref]/functions/[functionSlug]/code.tsx +++ b/apps/studio/pages/project/[ref]/functions/[functionSlug]/code.tsx @@ -10,7 +10,7 @@ import { DeployEdgeFunctionWarningModal } from '@/components/interfaces/EdgeFunc import { formatFunctionBodyToFiles } from '@/components/interfaces/EdgeFunctions/EdgeFunctions.utils' import { DefaultLayout } from '@/components/layouts/DefaultLayout' import EdgeFunctionDetailsLayout from '@/components/layouts/EdgeFunctionsLayout/EdgeFunctionDetailsLayout' -import { PreventNavigationOnUnsavedChanges } from '@/components/ui-patterns/Dialogs/PreventNavigationOnUnsavedChanges' +import { DiscardChangesConfirmationDialog } from '@/components/ui-patterns/Dialogs/DiscardChangesConfirmationDialog' import { ButtonTooltip } from '@/components/ui/ButtonTooltip' import { FileExplorerAndEditor } from '@/components/ui/FileExplorerAndEditor' import { FileData } from '@/components/ui/FileExplorerAndEditor/FileExplorerAndEditor.types' @@ -21,6 +21,7 @@ import { useEdgeFunctionDeployMutation } from '@/data/edge-functions/edge-functi import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' +import { usePreventNavigationOnUnsavedChanges } from '@/hooks/ui/usePreventNavigationOnUnsavedChanges' import { BASE_PATH } from '@/lib/constants' import { useTrack } from '@/lib/telemetry/track' @@ -141,6 +142,11 @@ const CodePage = () => { return !isEqual(normalizeFiles(initialFiles), normalizeFiles(files)) }, [initialFiles, files]) + const { handleCancelNavigation, handleConfirmNavigation, shouldConfirmNavigation } = + usePreventNavigationOnUnsavedChanges({ + hasChanges: hasUnsavedChanges, + }) + return (
{isLoadingFiles && ( @@ -243,7 +249,11 @@ const CodePage = () => { onConfirm={handleDeployConfirm} isDeploying={isDeploying} /> - +
) } diff --git a/apps/studio/pages/project/[ref]/functions/new.tsx b/apps/studio/pages/project/[ref]/functions/new.tsx index a640e634e41..79cba4beb28 100644 --- a/apps/studio/pages/project/[ref]/functions/new.tsx +++ b/apps/studio/pages/project/[ref]/functions/new.tsx @@ -36,13 +36,14 @@ import { DefaultLayout } from '@/components/layouts/DefaultLayout' import EdgeFunctionsLayout from '@/components/layouts/EdgeFunctionsLayout/EdgeFunctionsLayout' import { PageLayout } from '@/components/layouts/PageLayout/PageLayout' import { SIDEBAR_KEYS } from '@/components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider' -import { PreventNavigationOnUnsavedChanges } from '@/components/ui-patterns/Dialogs/PreventNavigationOnUnsavedChanges' +import { DiscardChangesConfirmationDialog } from '@/components/ui-patterns/Dialogs/DiscardChangesConfirmationDialog' import { FileExplorerAndEditor } from '@/components/ui/FileExplorerAndEditor' import { FileData } from '@/components/ui/FileExplorerAndEditor/FileExplorerAndEditor.types' import { useEdgeFunctionDeployMutation } from '@/data/edge-functions/edge-functions-deploy-mutation' import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' +import { usePreventNavigationOnUnsavedChanges } from '@/hooks/ui/usePreventNavigationOnUnsavedChanges' import { BASE_PATH } from '@/lib/constants' import { useTrack } from '@/lib/telemetry/track' import { useAiAssistantStateSnapshot } from '@/state/ai-assistant-state' @@ -276,6 +277,10 @@ const NewFunctionPage = () => { }, [template]) const hasUnsavedChanges = useMemo(() => !isEqual(INITIAL_FILES, files), [files]) + const { handleCancelNavigation, handleConfirmNavigation, shouldConfirmNavigation } = + usePreventNavigationOnUnsavedChanges({ + hasChanges: hasUnsavedChanges && !hasDeployed, + }) return ( { - + ) } From f622bc6ea0e333724f0b44dfc822379a228043fd Mon Sep 17 00:00:00 2001 From: Francesco Sansalvadore Date: Tue, 9 Jun 2026 15:30:42 +0200 Subject: [PATCH 053/134] feat(studio): dashboard integrations update (#46671) - remove "Marketplace" branding and naming from integrations section - remove "featured partners" hero with multiple partners - keep only _one_ featured partner to start with (Grafana) - gate each partner integration with separate flags to enable testing/releasing them separately ## Before Screenshot 2026-06-08 at 11 00 19 ## After Screenshot 2026-06-08 at 11 03 57 --- .../FeaturePreview/FeaturePreviewModal.tsx | 6 +- .../IntegrationsLayoutPreview.tsx | 7 + .../App/FeaturePreview/MarketplacePreview.tsx | 12 -- .../App/FeaturePreview/useFeaturePreviews.ts | 2 +- .../Integrations/Landing/IntegrationCard.tsx | 2 +- .../Landing/useAvailableIntegrations.tsx | 29 ++- .../Marketplace/Marketplace.constants.tsx | 9 +- .../MarketplaceFeaturedHeroGrid.tsx | 175 ++++++++++++++++++ .../Marketplace/MarketplaceIndex.tsx | 20 +- .../Marketplace/MarketplaceSidebar.tsx | 2 +- .../project/[ref]/integrations/[id]/index.tsx | 34 +++- .../img/integrations/covers/grafana-cover.png | Bin 0 -> 139077 bytes 12 files changed, 252 insertions(+), 46 deletions(-) create mode 100644 apps/studio/components/interfaces/App/FeaturePreview/IntegrationsLayoutPreview.tsx delete mode 100644 apps/studio/components/interfaces/App/FeaturePreview/MarketplacePreview.tsx create mode 100644 apps/studio/components/interfaces/Integrations/Marketplace/MarketplaceFeaturedHeroGrid.tsx create mode 100644 apps/studio/public/img/integrations/covers/grafana-cover.png diff --git a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx index 857a10a90a4..cf38d45a091 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx @@ -25,8 +25,8 @@ import { import { AdvisorRulesPreview } from './AdvisorRulesPreview' import { CLSPreview } from './CLSPreview' import { useFeaturePreviewContext, useFeaturePreviewModal } from './FeaturePreviewContext' +import { IntegrationsLayoutPreview } from './IntegrationsLayoutPreview' import { JitDbAccessPreview } from './JitDbAccessPreview' -import { MarketplacePreview } from './MarketplacePreview' import { PgDeltaDiffPreview } from './PgDeltaDiffPreview' import { PlatformWebhooksPreview } from './PlatformWebhooksPreview' import { RLSTesterPreview } from './RLSTesterPreview' @@ -47,7 +47,7 @@ const FEATURE_PREVIEW_KEY_TO_CONTENT: { [LOCAL_STORAGE_KEYS.UI_PREVIEW_PLATFORM_WEBHOOKS]: , [LOCAL_STORAGE_KEYS.UI_PREVIEW_JIT_DB_ACCESS]: , [LOCAL_STORAGE_KEYS.UI_PREVIEW_RLS_TESTER]: , - [LOCAL_STORAGE_KEYS.UI_PREVIEW_MARKETPLACE]: , + [LOCAL_STORAGE_KEYS.UI_PREVIEW_MARKETPLACE]: , } export const FeaturePreviewModal = () => { @@ -152,7 +152,7 @@ export const FeaturePreviewModal = () => {
-
+

{selectedFeature?.name}

diff --git a/apps/studio/components/interfaces/App/FeaturePreview/IntegrationsLayoutPreview.tsx b/apps/studio/components/interfaces/App/FeaturePreview/IntegrationsLayoutPreview.tsx new file mode 100644 index 00000000000..55c42690c66 --- /dev/null +++ b/apps/studio/components/interfaces/App/FeaturePreview/IntegrationsLayoutPreview.tsx @@ -0,0 +1,7 @@ +export const IntegrationsLayoutPreview = () => ( +
+

+ Browse and install integrations from a new layout with improved filtering and search. +

+
+) diff --git a/apps/studio/components/interfaces/App/FeaturePreview/MarketplacePreview.tsx b/apps/studio/components/interfaces/App/FeaturePreview/MarketplacePreview.tsx deleted file mode 100644 index a701e82504f..00000000000 --- a/apps/studio/components/interfaces/App/FeaturePreview/MarketplacePreview.tsx +++ /dev/null @@ -1,12 +0,0 @@ -export const MarketplacePreview = () => ( -
-

- Browse and install integrations from a new Marketplace layout with improved filtering and - search. -

-

- This preview is on by default for internal teammates and select integration partners. Turn it - off to fall back to the previous Integrations layout at any time. -

-
-) diff --git a/apps/studio/components/interfaces/App/FeaturePreview/useFeaturePreviews.ts b/apps/studio/components/interfaces/App/FeaturePreview/useFeaturePreviews.ts index f3d40b8a6cf..060b22c01fd 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/useFeaturePreviews.ts +++ b/apps/studio/components/interfaces/App/FeaturePreview/useFeaturePreviews.ts @@ -86,7 +86,7 @@ export const useFeaturePreviews = (): FeaturePreview[] => { }, { key: LOCAL_STORAGE_KEYS.UI_PREVIEW_MARKETPLACE, - name: 'Marketplace', + name: 'Integrations layout', discussionsUrl: undefined, enabled: true, isNew: true, diff --git a/apps/studio/components/interfaces/Integrations/Landing/IntegrationCard.tsx b/apps/studio/components/interfaces/Integrations/Landing/IntegrationCard.tsx index 934cfd17070..064d91a1f87 100644 --- a/apps/studio/components/interfaces/Integrations/Landing/IntegrationCard.tsx +++ b/apps/studio/components/interfaces/Integrations/Landing/IntegrationCard.tsx @@ -59,7 +59,7 @@ export const IntegrationCard = ({ fill src={image} alt={`${name} integration`} - className="w-full h-full object-cover invert dark:invert-0" + className="w-full h-full object-cover" objectFit="cover" /> ) : ( diff --git a/apps/studio/components/interfaces/Integrations/Landing/useAvailableIntegrations.tsx b/apps/studio/components/interfaces/Integrations/Landing/useAvailableIntegrations.tsx index 2dd5d116ce4..5319d27c7cb 100644 --- a/apps/studio/components/interfaces/Integrations/Landing/useAvailableIntegrations.tsx +++ b/apps/studio/components/interfaces/Integrations/Landing/useAvailableIntegrations.tsx @@ -1,4 +1,4 @@ -import { FeatureFlagContext, IS_PLATFORM } from 'common' +import { FeatureFlagContext, IS_PLATFORM, useFlag } from 'common' import { fullImageUrl } from 'common/marketplace-client' import { Boxes } from 'lucide-react' import dynamic from 'next/dynamic' @@ -48,6 +48,11 @@ export const useAvailableIntegrations = () => { const isMarketplaceEnabled = useIsMarketplaceEnabled() const { integrationsWrappers } = useIsFeatureEnabled(['integrations:wrappers']) + const grafanaEnabled = useFlag('grafanaDashboardIntegrationEnabled') + const resendEnabled = useFlag('resendDashboardIntegrationEnabled') + const aikidoEnabled = useFlag('aikidoDashboardIntegrationEnabled') + const dopplerEnabled = useFlag('dopplerDashboardIntegrationEnabled') + const { data: cliData } = useCLIReleaseVersionQuery() const isCLI = !!cliData?.current @@ -206,10 +211,24 @@ export const useAvailableIntegrations = () => { }, [integrationsWrappers, isCLI, marketplaceWrappers]) const dataWithMarketplace = useMemo(() => { - return [...marketplaceIntegrations, ...allIntegrations].sort((a, b) => - a.name.localeCompare(b.name) - ) - }, [marketplaceIntegrations, allIntegrations]) + const flagGatedIds: Record = { + grafana: grafanaEnabled, + resend: resendEnabled, + aikido: aikidoEnabled, + doppler: dopplerEnabled, + } + + return [...marketplaceIntegrations, ...allIntegrations] + .filter((integration) => flagGatedIds[integration.id] !== false) + .sort((a, b) => a.name.localeCompare(b.name)) + }, [ + marketplaceIntegrations, + allIntegrations, + grafanaEnabled, + resendEnabled, + aikidoEnabled, + dopplerEnabled, + ]) return { data: dataWithMarketplace, diff --git a/apps/studio/components/interfaces/Integrations/Marketplace/Marketplace.constants.tsx b/apps/studio/components/interfaces/Integrations/Marketplace/Marketplace.constants.tsx index f0ab5d79339..e80fd564f0f 100644 --- a/apps/studio/components/interfaces/Integrations/Marketplace/Marketplace.constants.tsx +++ b/apps/studio/components/interfaces/Integrations/Marketplace/Marketplace.constants.tsx @@ -32,14 +32,7 @@ import type { export type { MarketplaceSource } from '@/components/interfaces/Integrations/Landing/Integrations.constants' // Defines featured integrations and their order in the featured hero -export const FEATURED_INTEGRATION_IDS = [ - 'stripe_sync_engine', - 'grafana', - 'aikido', - 'aikido-security', - 'doppler', - 'resend', -] as const +export const FEATURED_INTEGRATION_IDS = ['grafana', 'cron', 'queues', 'data_api'] as const export type MarketplaceIntegrationType = 'oauth' | 'postgres_extension' | 'template' | 'wrapper' diff --git a/apps/studio/components/interfaces/Integrations/Marketplace/MarketplaceFeaturedHeroGrid.tsx b/apps/studio/components/interfaces/Integrations/Marketplace/MarketplaceFeaturedHeroGrid.tsx new file mode 100644 index 00000000000..9722c979052 --- /dev/null +++ b/apps/studio/components/interfaces/Integrations/Marketplace/MarketplaceFeaturedHeroGrid.tsx @@ -0,0 +1,175 @@ +import { useParams } from 'common' +import Image from 'next/image' +import Link from 'next/link' +import { Badge, Card } from 'ui' + +import { IntegrationLogo } from '../Integration/IntegrationLogo' +import { getMarketplaceSource, MarketplaceSourceBadge } from './Marketplace.constants' +import type { IntegrationDefinition } from '@/components/interfaces/Integrations/Landing/Integrations.constants' +import { BASE_PATH } from '@/lib/constants' + +const FEATURED_INTEGRATION_IMAGES: Record = { + cron: `${BASE_PATH}/img/integrations/covers/cron-cover.webp`, + queues: `${BASE_PATH}/img/integrations/covers/queues-cover.png`, + stripe_wrapper: `${BASE_PATH}/img/integrations/covers/stripe-cover.png`, + stripe_sync_engine: `${BASE_PATH}/img/integrations/covers/stripe-cover.png`, + grafana: `${BASE_PATH}/img/integrations/covers/grafana-cover.png`, +} + +function getIntegrationImage(integration: IntegrationDefinition) { + const featuredImage = FEATURED_INTEGRATION_IMAGES[integration.id] + if (featuredImage) return featuredImage + if (integration.files?.length) { + const heroImage = integration.files[0] + return typeof heroImage === 'string' ? heroImage : (heroImage?.src ?? undefined) + } +} + +interface MarketplaceFeaturedHeroGridProps { + integrations: IntegrationDefinition[] + installedIds: string[] + primaryIntegrationId: string + secondaryIntegrationIds: string[] +} + +export const MarketplaceFeaturedHeroGrid = ({ + integrations, + installedIds, + primaryIntegrationId, + secondaryIntegrationIds, +}: MarketplaceFeaturedHeroGridProps) => { + const { ref } = useParams() + const primaryIntegration = integrations.find((i) => i.id === primaryIntegrationId) + const secondaryIntegrations = secondaryIntegrationIds + .slice(0, 2) + .map((id) => integrations.find((i) => i.id === id)) + .filter((i) => i !== undefined) as IntegrationDefinition[] + + if (!primaryIntegration) return null + + const primaryImage = getIntegrationImage(primaryIntegration) + const primarySource = getMarketplaceSource(primaryIntegration) + const primaryInstalled = installedIds.includes(primaryIntegration.id) + + return ( +
+
+

Featured integrations

+
+
+
+ + +
+
+ + {primaryInstalled && Installed} +
+
+
+ {primaryIntegration.name} +
+ {primaryIntegration.description && ( +

+ {primaryIntegration.description} +

+ )} +
+ Built by + {primaryIntegration.author?.name} +
+
+
+
+
+ + {primaryIntegration.status && ( + {primaryIntegration.status} + )} +
+
+
+
+ {primaryImage ? ( + {`${primaryIntegration.name} + ) : ( +
+ {primaryIntegration.icon({ className: 'w-10 h-10 text-foreground' })} +
+ )} +
+
+ + +
+ + {secondaryIntegrations.map((integration) => { + const image = getIntegrationImage(integration) + const source = getMarketplaceSource(integration) + const isInstalled = installedIds.includes(integration.id) + + return ( +
+ + +
+ {image ? ( + {`${integration.name} + ) : ( +
+ {integration.icon({ className: 'w-8 h-8 text-foreground' })} +
+ )} +
+
+
+ + {isInstalled && Installed} +
+
+
{integration.name}
+ {integration.description && ( +

+ {integration.description} +

+ )} +
+
+
+
+ + {integration.status && ( + {integration.status} + )} +
+
+ Built by + {integration.author?.name} +
+
+
+ + +
+ ) + })} +
+
+ ) +} diff --git a/apps/studio/components/interfaces/Integrations/Marketplace/MarketplaceIndex.tsx b/apps/studio/components/interfaces/Integrations/Marketplace/MarketplaceIndex.tsx index dbfb503b907..eded2dcfa2d 100644 --- a/apps/studio/components/interfaces/Integrations/Marketplace/MarketplaceIndex.tsx +++ b/apps/studio/components/interfaces/Integrations/Marketplace/MarketplaceIndex.tsx @@ -23,7 +23,7 @@ import { type MarketplaceSource, } from './Marketplace.constants' import { MarketplaceCard } from './MarketplaceCard' -import { MarketplaceFeaturedHero } from './MarketplaceFeaturedHero' +import { MarketplaceFeaturedHeroGrid } from './MarketplaceFeaturedHeroGrid' import { MarketplaceFilterBar, type ViewMode } from './MarketplaceFilterBar' import { MarketplaceListHeader, MarketplaceListRow } from './MarketplaceListRow' import { IntegrationLoadingCard } from '@/components/interfaces/Integrations/Landing/IntegrationCard' @@ -208,14 +208,13 @@ export const MarketplaceIndex = () => { const activeFilters = [category, type, source].filter(Boolean) const pageTitle = useMemo(() => { - if (activeFilters.length !== 1) return 'Integrations Marketplace' - if (category) - return `Integrations Marketplace: ${formatCategoryLabel(category, categoryOptions)}` + if (activeFilters.length !== 1) return 'Extend your database' + if (category) return `Integrations: ${formatCategoryLabel(category, categoryOptions)}` if (type) - return `Integrations Marketplace: ${INTEGRATION_TYPES.find((t) => t.key === type)?.label ?? type}s` + return `Integrations: ${INTEGRATION_TYPES.find((t) => t.key === type)?.label ?? type}s` if (source) - return `Integrations Marketplace: ${MARKETPLACE_SOURCES.find((s) => s.key === source)?.label ?? source}` - return 'Integrations Marketplace' + return `Integrations: ${MARKETPLACE_SOURCES.find((s) => s.key === source)?.label ?? source}` + return 'Integrations' }, [activeFilters.length, category, type, source, categoryOptions]) return ( @@ -239,7 +238,7 @@ export const MarketplaceIndex = () => { {isLoading && (
{Array.from({ length: 8 }).map((_, idx) => ( - + ))}
)} @@ -251,10 +250,11 @@ export const MarketplaceIndex = () => { {isSuccess && ( <> {featured.length > 0 && ( - i.id)} /> )} diff --git a/apps/studio/components/interfaces/Integrations/Marketplace/MarketplaceSidebar.tsx b/apps/studio/components/interfaces/Integrations/Marketplace/MarketplaceSidebar.tsx index bac1a6e98a2..5ffbcf011ba 100644 --- a/apps/studio/components/interfaces/Integrations/Marketplace/MarketplaceSidebar.tsx +++ b/apps/studio/components/interfaces/Integrations/Marketplace/MarketplaceSidebar.tsx @@ -70,7 +70,7 @@ export const MarketplaceSidebar = () => { href={baseHref} active={isDiscoverActive} icon={} - label="Marketplace" + label="Explore all" /> {isLoading ? ( diff --git a/apps/studio/pages/project/[ref]/integrations/[id]/index.tsx b/apps/studio/pages/project/[ref]/integrations/[id]/index.tsx index c71e4a6e142..7f1980fa16c 100644 --- a/apps/studio/pages/project/[ref]/integrations/[id]/index.tsx +++ b/apps/studio/pages/project/[ref]/integrations/[id]/index.tsx @@ -1,4 +1,4 @@ -import { useParams } from 'common' +import { useFlag, useParams } from 'common' import { useRouter } from 'next/router' import { useEffect } from 'react' import { PageContainer } from 'ui-patterns/PageContainer' @@ -9,16 +9,40 @@ import { DefaultLayout } from '@/components/layouts/DefaultLayout' import { ProjectIntegrationsLayoutDispatch } from '@/components/layouts/ProjectIntegrationsLayoutDispatch' import type { NextPageWithLayout } from '@/types' +const INTEGRATION_FLAGS: Record = { + grafana: 'grafanaDashboardIntegrationEnabled', + resend: 'resendDashboardIntegrationEnabled', + aikido: 'aikidoDashboardIntegrationEnabled', + doppler: 'dopplerDashboardIntegrationEnabled', +} + const IntegrationPage: NextPageWithLayout = () => { const router = useRouter() const { ref, id } = useParams() + const grafanaEnabled = useFlag('grafanaDashboardIntegrationEnabled') + const resendEnabled = useFlag('resendDashboardIntegrationEnabled') + const aikidoEnabled = useFlag('aikidoDashboardIntegrationEnabled') + const dopplerEnabled = useFlag('dopplerDashboardIntegrationEnabled') + + const integrationFlagValues: Record = { + grafana: grafanaEnabled, + resend: resendEnabled, + aikido: aikidoEnabled, + doppler: dopplerEnabled, + } + useEffect(() => { - // Always redirect to the overview page since this route should not render content - if (router?.isReady) { - router.replace(`/project/${ref}/integrations/${id}/overview`) + if (!router?.isReady) return + + const flagName = id ? INTEGRATION_FLAGS[id] : undefined + if (flagName !== undefined && integrationFlagValues[id!] === false) { + router.replace(`/project/${ref}/integrations`) + return } - }, [router, ref, id]) + + router.replace(`/project/${ref}/integrations/${id}/overview`) + }, [router, ref, id, grafanaEnabled, resendEnabled, aikidoEnabled, dopplerEnabled]) return ( diff --git a/apps/studio/public/img/integrations/covers/grafana-cover.png b/apps/studio/public/img/integrations/covers/grafana-cover.png new file mode 100644 index 0000000000000000000000000000000000000000..43a0c31dda1f3b55454f7c9afa02428ef8bc0084 GIT binary patch literal 139077 zcmeFZWl)=4yT^;W6TbTAbj)U4kVi-RJD* zefIbBWzX!HWXMWpZdv!b?0@|hQEDo3xLD*^2nYzc3i8tG2nZ+u1O%i|3^e#R?wM>~ z;D0ckA z$N#$ZkRB?^#L1cT@eR?zjn9lt(-X((FJ%H0iT{2Tc0_K>%88FDC@9bsPY?6`^MeFI zs61WpB;p(9YhBj#bR6m)kScqI+?v78&HeE9MKTD?6rk}xysKLpqKx-b4TdOs;@sSv zwq(NW?wg8vS?U(K0jhr;mL5Kb=m^)lzb7X4)`fdFojw`nrZsr~=aM7{=;JU%yFR+O zd?+a^bJb2*I4aIs_Hk)jef=NH44%@5UwF*-k`iY!606#!-+GQIGi?7ljStlefKQZK z9lD>-;rzevcvC!4UUGml^CSK3zYk{_xk2=0sz88+B_@ElPVT?w2R;qm;wbqTDcRYh zxLMN;as$-=I>`gl3jjUF!!7ME^bY4j30L9dq$GvUnV;uC%*@P1FBoK#R46*^Ylh;f zR8j9yU*ZW?#iPB%ef`f7=-QJ?$6p{xs@6KHYPs8Mo(!2!QCN+n9=Kgk1Cs{777h)` zKJ2a3>_49Mys2pFKB_T&KlOa~oP=71PV-dtkf-(NH<4+Xqf{&#S4d*ymF01=u3*T> z$QY&~e8HW?ZT-QTNAKqk<}!}%r&#|7YwJDv!k^ww_0T(Q=b5li$s}72>Td^C$#4O$nkso zrukvzpe$dRi0R|r9Rvh}N~LMNs)C9FAoA@S!Afr>p6~91Rrj+UiD!c>oRkbu70N5O?YGfoT2C4`xnn20l*)b!3Z-U_W zumogHZ!+H+`0ch>$p8VnAN`qnr0HC{{=2j{BKCDDu~WWACBwGn4ldrSL41E&^0x8UI*T zC~`!qn+yU5GXZKKPc(ehT8V96yXwv@Hrb*-Kedk@gc2ouAFbgxjuILD9NBiW&~tEk zByrs9TGO_tUcYqvoJU~L&&bA>>+rB^&w2~sg)s;|$C@6rZYLD@o_3`eD4GdAR$^OS z?pRmlT_prS!{Ws@<=usX^L$Sgh$9l)h{`W37~=UApT&ZR*&YBr2_n0xTwbdo-z&~s zcamI%{P3vrNiTD5r)=EK-jnLDS*m={&=I(v`ei+tC(`H#Y{sKO=GatzLXDMP(8t?bB4EkObKVOSsIv1KA`i*yzQ#z znbh?Gld*HDnu|*`p{7w;S)NZ6>sw-|uZIVo$a$~v+!b*JkgasV$S+@}^fvH^^Kl*1 z<#rwvG@6>0)-`E56qhR=f`(tXI~wr4=V|wjjf@B6-|-E4U(-{&&*k?(chW6d56BDH zw0_6JLKnlBhK5h3m}D}tb8xsQ_@lA$`z-KesUaH+3(I=3c9ZQ+Ig4A1D&iwlpP4kq zde&kpfI1*u^zqvEK|1atMYU6&h>3FUlJx1MgalNIehMRkFKY00-y`<^knvMiyvQDk z&qY|vey*ozF`p4EGG6R-M@1~-x0(93pphSRi#_eUkQ?voq~;}jibD3+`ue)iY(g&g*MYxl)Ngj+vmS>t0nWFo`Bg;DHOHQ)&y?uL^7iJenI zaQ}*^R*!TXhZl_k{1FHpW=MF`Wdw2o9Vklo`K=ZHu%f+FU268DKtC;9Jn_)0-w}d( z@9c9vIU*?*aaT2PC$fcnc)OZ77*t7iJ*S}7!(h^L)-5(28-ib$pUzh33Gxd;&8(YhK^Xlt;bl2|ZuWtji-XU6XiB%`I3_6V>rqbgh&@0Y>8yt!meLNrb;*PC-JHA67g+EpVrKzY0QBlo1Us3VyN1L;- zp~n(WqxCG>!)ZrN8iu8IkFiX7xiyu4wG_TUPJ<)d&#J8Tl?{yIi}@rp_zorH58rJ< ziW^mnjqoLBw8T2{-jti(4w76QoU|AhzqtW5Ej$HZu5d@lLT50Uaui7ny#(x6TZ5p_ z!=M$m1fqW|pFZUJ9Fqv;7lFmp;{ZJ3zOMbVFdfIYF5A}TO(~u4HdF3)+D0;Mn(*A9 zU!$SP9|)_es@glwXtrB!%o}7h%~mh0{^0je$o&-}uUEGv_ps*ZxGOt}+4c6C(eX#nJW`$BHIqNZ!O%K=Yh=RK5l zrP4RE%11Zy+6WIU1BLdU+v zQ7pi%*o_8uvhGV=M8;*IF5yo%U*SDVO<+q-71!u+Vsps8yIb<)*zNP&EUr5`HnR0* zeNy=GwU%aTomxcfn@Ar5P;iddjJ4Z^j83i9Ex2cOa@YKyz$1A^7p(dXWwgzpdN@*K zw_GSSj`73SXz4xV?&tX8qbPLFTzG}hR&S8jh)vuiG9yN$|9kf%Hr?&X? zBootPx0GhLJ>-5pC3Tl17sVwJs~Fj*qCM>I4FLt1_7yQ?Jq0arW_PUT@9m_hmZhi& zr!_=Q9hEjWhvxwfr#)ngTif>>IR?)g7m0AlPP}pJH%(|Luvsmt|>xKO*Z# ziPx%#`*OO})6=|iSi0Uify&KhabK*IpCtlpGh#E~; zPEO7t^!mu;m$5e?kOg!ayv(->*bwS^Twh^@jA`Y&E>3N(uKLsw4q!=sFjJ$poT9jQ zZCi8bMs;#ZpQ>K#(Cc#0XrNt4Hko_*&@#~wp9s$qa+N>A6SP+}iP!$>KN~9lLqwGz(W3_9^NZyJBV> zD2rN==lV{B{ij;EW>4NEdee9EvzXJg&!J_SqNeBLukiSS{O4mZxBX$CrlH~B7V1dc zc_s{+Al72GVz<&9R{9fYqVwbaN~|>GjjBd)Un`z5jdGxp;_Xx)`lRO9F|8cb;2A2j z=G2U|rqlwuh5?(VnI39r1z{+b_3d$6qe>LBWB2`tXib}zUwF$pAZqOj8hB!Ax<5qW__q)U2kt*zv709y zaRm6O#le_fVp>e*{et=5%=bTwdISmOHLcjemy-Oa!aaBFZ7FdbT6L6&by#cxHp3@9Qj28&@tNA)x?m#A1kgQI-Ckg@gEx1TR4|c0^!< z|1Z7eHdl09YGF6fOkt_`WLD49&7B+YPKx0Epp5al1?Kz1+_TK2 zC;$0kLa64dTHP|&-GB6G^U-d(Gl)9iX%mkN@J1!4|1&?_eA(Q?Hc0)tH#7t<24;uB zchmi0`7ICni8KKQk_p0>p6y%F6$k0rXFHE-{SlMVR5e+~oadeCWxS|oC4cT3@ja}h zh)JXytL=b!N&l5&V)ZbE*8ffIBWSv$u;=bD@6*|Uu9JC&*T=4^|5aW&v>)(7S>ka+ zJ8QZhl9OAV@7B+1Z5LF0p2YBHYXba83_aJB8@)$|@PJ1D)TI~+q3|lZT4r3b1BaYD z61LV=7F$GSN0pzHCnJN5rl#!v%G_di%Dx4fPQeWFSmDsiVrOD1Q`6Swy?ZLJtfb8t z9XB^&1_hIb#F9kP4!^_-Hmn?qr5;84bxXD4Wm#r|`I5S3_Mp7Fx^%aDHOJr>Q5BEz zP?w_e#NVhBJuhahkoE0b8-SEaLN6pwYViej@NY6pYLInJ&Ib5Lb@h%NF*LsIo>d*SB~MPk&_jhfLvHEB7er)k zDiwiex=9c$A4WKxGtOvj55zNf`h3`WpOzSEN+fK=tYiDwZgRYMk@M+lW^{4}UW+N@ z22D~ZYNV)kIU33b&>dcL;Zg~vdLH$A{-~*8ENi&lbjJevnRg}5sIGmVjy$k9k0 zS}_|$Z|dkFjpzeN7`Xe}42@`#gSZQzv67FfqBo?2^eIfL#Y!A)$$1Z;0IQqBSO4)X z17h?L=}28-z(00?A`!_E9Gq}G!}yOw#|S2X>kAD3tH)Lf{3fs8yivEYAbdo@4j(42oap50Q?Wb5)rsn3PC7)(?9Mwgo zsFqG{Jz(q}g#ol4g`Rzob_124<<+Nd0Ir65g|gY-5Ufv9PN&*BTJF9^(HpJ^L7VSM z<23d4D`I04LLo90^T~tB%jFxUyi6LVrVIkPDui1kr2DBau^Hc5cJ`Ku<|gONly9Vbt@}|hS;~IQPPmm(VE_JI55hw5Z6HQ0kPed4%g{Z2gli-E z-GdntX}C`Ve;dAcIG?=Z>lPo9AK1BtBhvX!z9cTqR6C zmcDMrMVOc+ zSjgs4SlXQRr^cAYgHH0>xCJ@46UHmzS3E0gih3;$xJwi#uLpRotq%aoY{ML{;o{`r zps&?cdfbjnn|!2-^m){Wjc-P7o4bm0@*5x#YJB^Z?lfW!Xt3%}s0v(*p$b_2eJE*P zkd? zqPwT*{_!#^0W)69-oC0`7SNVpxc~N>a3;XqEGVV0xmfD3%+x0Au>&5TzG|Tt_h`Z4I@_&7c=GVhy#(Vb41$DmoGk zX&luG3Kl#nmb1WofcT{F6$-_!hN?i!hnXHbMhLCY;he@q!D>#92P#dcB|HOxm)0q= z6<^9A!PxA@zNc*=TtAD#>P&&NUmD^I;MGuBT19$`0XL%d=|*p^+l=+~PA=R2QW zHo;$N@KC`>l<{!sEq0|10j^aL5JN{sMixJZ;tKD6=i0A<-J$C>*~pA;%f2gn=|P0V zfzni#fA2U7N<>9nK_u9r)y4l{wuS^31Z&+>3C%^S@!II)i|_=fIXx1 z&fo9jcD}#d?Z3bNtCyl87!bjYuo`Je^ zqV(ax$7eGP)^th3nyx8mHS;oW5@VgWG4rSn1!)|U&V!DJC$2|FzhjEXDK-FlWvt#s z-eH*^@N=!;6#n$ggs8KWKUeL=YK!pc1@{&hLJp5)SOEhSh6v~^*-mRsJ(~2EZ?JPL zc4?@&&QN@ygRp6R$F4stMfk)er62PY^8pVp?3e1x=OL0-*@CFszQkQu6BL|m4=>*a zoxe1vS+T%~CliTR5xn5mYw*y@K%vRu8s>hyV}Pk4eGf^lo617y$on{rwuNA@^1^sS z2pxniVTFU9a+ibG6wY7o^_d8a0uk$CB!bZ;79uLs#D?oKwqGrQR z_2md|+e0@mI!vg&2d0n5{2!Jg*hmtK-~xv{?TR_{NmcW`a76AD9|#bp(PWxy8ZVF( zFM7!DF_-6kib;J&ClxWx;m{i9(0;+&e%n5(M~w|enE)s%e#k9Cp{`sFD2lyoey`1H zdt|de0a~r36k$WpfGf|)RDRcW*8?dD>fC{>AyO7&TUv+t{(2*KUz!lXsFX&Pt8@$p z14JsjI0<3cBtNh5CM)UuVknvp_5=4C(t-cyhjR?^(>pkS1H5 z3fhY5UB_e6*!=I5ldpOB7<6Q(^YK3?%i8jb>0HcW*)#=NMB45aY2zXpNMG_VnjuZ}D%EXp_RvMw<_DqPzW zYhW?N0ZWHnexfv!5@WA0lzO^%+1ocCviI95{AH(6KA3eG(R9K3gmP}sH^jst5}5b{ z3aes%%XFH0>K|`74gL_>kf=fZuasL_>al%KS~3+=ds@s#_p~SFEI9TewArqEyED?$ z&M$Hcj&Jur=`MNxKyA*v-cAr}WSQ9}|EsCl-BW#LWcPG~m==0`*&PwL(C=Ih%gHf# z7`)-Tn(PVKr(SNhuh839Duj)_)-Tw0A2%9I z>zs24F$j7FxQ1(GhE$d9#Sy6ZO=uqthl>V~aO^H$Gx9R{hu{Jw=T*hted($XzCB(V z1Rs8n(r7inBC{d|&MOu~yyv!_F(Y>W6i)iCmR!pYL*HJFlj^BIdIT#PMJgPpI0zZt z#V*5Oz&fj8d#&NDL!7y8T)u>!ca&)k{X_=sgv9B@?y1)=bwFdoe(t6wF-ea zdanE9r=_P~MkToI967co;|}32JV&4XLiGYp*k1?gng9B^im{8c?sMeG%p@d7hK^eX zg`L2t)mbQ5(j-L!{aqKH0bi!du?6d+q1Rw^tCRM5xAiuXPafKMYaT%5V}e~UcsAE_ zRXIWU7N1zh;eMXV235^)EDe%eg)~}G-Tm!oYxBIM%(9kQ!^lYSZq-wVC8(Tfz zx+JmD1fWy-rw7)zLg};xrAY_Kkr=xPykeey`^WZ@uD4GijObywIH2q@`a?I(1WEiT zT?FMHbr)2pN|t&4ZL}{0h?KGZ{K5D+_XW&>G3YZc#n$tP^l$baEp}T`$O_nh$WeQ9 zcR?Rwjv>n@9)DZFi+$ozQkB(<2Wh%7R|^&mm(kYlJktUBkQO~g-#DGB1i?en_Cw2s zX&TsdAYoYdCYaLqILfVE&lxs;=1_uGk#^dCWb}@ew3nr6_~-p72wI?h(gAjoknV32 zlSPeo;w7gzxt78xL?_HZgjjI^!Ev&p zo!e*#RSL+$mXMsBoS7k9uC}9ATn?sP!N+49(Mf#e4HwIq`@C9R+83IAs4xzQ-cU*} z9g+v(jL^GRk%>7F#vlyuM9B=rQcb!NeYGU`UdVubtjri~VonCeMUgZcVl{k_!dXER zfgL#sE?x}bVxu^A-hT*?%Zb#|(xTKf38RS-hPN-?sprc z#GJPz>^zMEp3U2jXDa5tj!eS?HbGplD*>Y6XK%~|SMH$Wmj2+NMyqKs+gJSHskTG% z`(i?YkR@Y+XyCg-20jk4Qq=s3Ve-gT3 zsA#a@C)bbt+VoD%xXRgzSHq!3IU{Tp?H$7oZYR}C_uh-RGJV%JBQ8- zZHGaGATnoclz{|Mf8%?{gsG)>%^_l;b|cyT-Yn1X79#lD$#)`Eb57z>w#bfJ(gat0 z@L6&R$hCC04&F(2eJMH_6406re6{c-azBRVSQESMyUJp!)3kp^2M^5^GY+@^;XQJQy|Uj z#WRcw{W`3N$>Zg&klDI?z!qwgq9K7fcszxGL&kfo>sf zZ-V3Epe;ZAr*Mb18?-zjx$#`!=l6!F^tdQmX8WB_BUjhiAZQkNNrd zrgwGt{p)Z+9^OmIWmDElVvD)>+`YxL+~rH6oGTcDoF3mxYGJL&-G)w!)Zm5qRrZG=WGQW7I`#J~|3>E#UyGCXZJLh3XpGbbUQQiadEKMd{bo7Ah3s35aSuRwf@@FLE8G-wpVDbYXZ=Oqg$M&DCvgS3FhxVSSp%64-ThdUV~< z;aFTX!XfdNw0@5UdIxisWh5R9@H^sYaj`GY&X@7bmtRCd8Ipd>oMgQf6RkGzO@`xjyi){phT4Wbb_njRqIY~iss zws+)`2NlIeSG9rAM}(c|X`CUSu9v_x(=`rl)%p|U^~!mErwT^9 zQXsS+lN71-#@}&}1I4+VdQEmwESi2kpRxNevbTv;Wut6KI&Wc?O~G3SlNFj0wdAw8 zw7hyj7ejYLb(dbZpi~l`Un%%m{mR_a*~rR5p6-SItz3!Z(W3ZM_ynyT2JtFXP-M&; zK1y)&+g;sp89it)hp4@?;5o+xwpq%+JDzt19Y@v1vz$Q6viRT5ZhHsd8C0<0h+ii3 zVp2@QUHO&YV@xwAcE(9~D-b}UNnPSKgo z&ECQsq9qX+qzBl>gft>n(|IUKoP>@~-5)PTu82A z)@Ob_NRmI@1AXRWr-D2jad?LjKPyeiA-nEoJCd;IyTt0H(Euwh`6IgR*}?tpC=w_G zk_H-|EJXdE;1qyRc1@ea`-z^eBT@fTamM;SSz%~?#M`XE1Y}qr*wMzFrrMs_6i0+a zZH6?ii>qDA(gX4NTVmgHKinl5_re>c)IJAcEmrGrENo$Wm$jy5&ftC{#1nGyW_R}a zVNXb41=4i~Qct+3&6Uv)iXRb?izO`~esFNSf97EAO@ghS!P%fc$Bc~6tr5AhT6tK92NjBlweM1g=+Bb!LhdmxKjC8A* zBMxrbX^M7dY?s6Xp5Yzsv@oHuFR9iHrX)~eYJ8#aOZ`QoMet#k;-$CWp)lp|qT|pD z^zwYU(0N}X50u7dfJW&@@OF!!wC2DKQoaU}j9&-J3qTPu%7d<_syrncb#gy+a4{w^#mweN( z>K_Q%KVOn_Swe@R&GU;RF{+IwJR%fRac}%q43ZW1hHT2YXf)GmbrQ*XA;qq(5Bs4@ z20i3v==6d(HP8D{Q4Wsk@NigWIP1P9m*RLEMiOMCqyYQ4J%%xhX05#^dhcNu@OILz zP)$VY2=~Px|4T}iV>IxY8D`JV_T=jJy{}NRrPn=eSJds7m$p`!KF{4o5IKSn*+J3> zwOaa!wN*(DUJ1ELk3h=&b)<^Mnl5NPp|9~KT7}hqd^anzg192oGT-l`+`BI%^uU6k zkR^Xs15&HJyX7N}r1gTb-zlZeVyu;0Vz4KT)$ffJB<9@F;Y3l~0g)n4nTLmv`&!N@ z8P`VIO>K=+h+*yl!fVCA4v%yhJ<6M zN1`%pAAic~RY4EZ2tQt)zkFmI{$ds?_MR&*P1e1NdOxR+&hgn|uN#VIDo$`7DznJ3 zk_p9z+ty=v@O|K$n_-JfALJmaYUOYE`ynKw8}0Ff85zdj@q^mjtD=WLOh5NZ;L}`> z_M0Z|a``P6HagD=igv@*L(T4A(*{PEUr2k9F(g`L3n;hqVG#T~9O=>v&Z~Ivnq}u< z9by)wJ>;k_y^3Nf&m>JSD=+{7)@Q|i9`A+#LcQ%b`)G5c>ssHYC2PVu(`NX--rj@n z?xKH^V3+M}xv;D*C5~ZEh0ZP2ZK04TCDJTRq^m^$Amb|FV~pH^kpH7+F>H(QSU09pCUN`*vX6X_{EzbHpM z74ftr#d>kB+{&entNI5WfSY-t9>3FnDHo7SE}z>arjBdf?D3&EVq^b%Z;#{NA4#TJ zRQwz<$oW5BwJpqHDRmRdSGPTotR|iw)sTEr@!d z|5kzQa3hTRGed4rH~o9zv#z^lpK);!rr?>ZLz{QFt_!UEI6mgJ8wIGN?IsYX3p}28 zi~fWl(`g-J^~#X5@TxdVY9G>?5q7nTCWM0nT@i|6ZR^RN^Tu>w&+`NYRk}W%IPe|u z2hm`2liAWqlQI$>s3GE2d1-U}rOQ=o<@alN6qbPFJV*24Mq&u!sx6 z=>su{;0MofPb!nULk=ve>H2D~pS$aIF zXua_w>NQyC?iicj7dz9g&slEiZhm9|c2^t#KC<`@XbN0gE7_Yg;ptYA8d{hZ?(R+p zeg$xXz6v0tT%qL$T<<$~2IAFj1Svb!a!M*kIz{VZfN_th6yG>QzYs;yV(RiA9DhGV zl7QjVJVuDE1M_i3a%g87*#-~Uz1SKjNxxT@Gb>;Rhy7|6sm4>smR)RPwOR<<7x#e- zAX-UA$6Q1)<&5!k$RBiUJ{bQc7{>7CcQcHYJy$*W_?$wDVq@_t^vvZ#fD~}$?X+{7 z+CkGwlf_UrrLJTQnFQ&&t@WwCqAh5#4Qw!X0Pao)+o$1zQ;+hxKH^`bM9c)#;-e`*5j^Q_haW3N8*)qz($ z+ZZo1*kDn@>w(4bGb;Q%8Ag{}BO~j+Pt%KJU=BM%#nCBO6qeDX0QL8NSm{{$aAX!-L{eC$Lr}I@QE*u5_@RODt zhe9ytwDU@IJrnur#j~l}JIa@-wG7MK38Lf86a`8A$0!fcffd!A@z4iw#5|U-nU4Uf zgobwHwnnNhHHxcQkX|fCy1iKiYVdUN(2VM6`oJ|nyywMYI64i4%hAkfCb`kUpQ(B>Z?hwV*)b+^Y%j*1g9TE0Ygti$04#HU;2;*YHBHTB}W`H;x>M zFDWI}qSk_)MBZn9T)XGDF^ba^?Mul~z@VM_6~PZ}O}W1d#J}LqD7YrhPVHSXK1Qm) znTiCo3+CN{9_6UPNB&Ty_NSSOrG!Tb!vtsQuW+Rlc1H@t-bCuiPD&aSaze$7Ju73& zWVXVHzc7SjxzXkua=qGPxm*bjZTBh@{sV9Lhn>PV$lAYP@#^&j3sQ$rT_t)qHMZ4I zkJLEDf4#ulJr_ZRE|Fk^XQv7oyqpPQ`kBwV4uEMtJ4MPV zc`Eme-KJm7eTRG9odO}@x!VBfQOznDHLhWux=uAEFhK0m(|=7|(Fu(Y;n%wt4;}>o zl%`Sy5o$>>bR?kf84UONFr&qpNW3y#Q%h$GF1n79$!{WDAjgliz5B+miis)qbWTN~ z2@tE?FDogTuKe5}5QCV>eu0Ek3;H=fi_PAeikiOkz_1kMd%IM&PqkZ##9zIL*gN}s zg!!SWw_NlxvRHS&uP$6Mfh{ZK?UQ|G8JxNmx&6Lo`4kkbH! zUUBTc%pV&6vnfo+wFiS`-FhUoO1hUJk{Zt}Hg3t6jma=G(_d zcgFXi20mq4<`pC-uRW2Py1rF&aV@Z)qJZ3)2nuye1!D=~3=Q+14IBzLqsgY&eE(Ks za6@#~9m3fQ5PyR%&CE(*w^SeXHPf;C^T)|O(Q>5gl!GT%jy+pnKR>qT%|f6aRlpcJ z_cR;49bWe+l!g$=7Ci0g_{o(Q-@{2VocQ536p3a7&gAX3nQLOR4yX5CoV-&w)cvJW z{4`rQp_5vD*KZH-%`4ji($LQ&}=y~J8I#}_sv zwJAHQqyCZl9SBee_;Fsq7t^?AQ?3Y|sJR&Epw@cYZ@Fz}@6NvE6=AV?9oh@=uO$Ai zQZP5CsaIIt)as7{BpDB(i!2ZTv}Q+N^Lzsje{WNan$z9S5!^K~iVV*MJc+>^*nROe z-IDFt+DT0Y!L`Me>1_S zHUr(Im&ZGc^OeqSVWbKsmD8=*XcR0T z3UO~X)XXg`>O(+NrJq>xBGMfBPYbOf5{W(-#j|sRCwk{bY8B3#)jxkaeCCNlk^hwE zeExC$GGW$f-ZQ8mFcyiFAvIZA=~*ORMqwE5tNrhZamJ4EKfBnhIs5<}%9T99@4ADb zvtXNbaxQ~J|G3HEwxI2JoEQ`2?yfiuhWsKB@tARCeeV}JEM7`dl+=BF6foL^zp>!O zw-&DeTR%AUTZ@Y!m>Az7_I`pntUs*BKE&Pr%7MUh&6}p{{twGLT2RZUHy=C`qlivb z1i!^V#++oAC%zo-2fIwgH}8dQm(3r}8^m{N1hxeprxz6!{m8-Yo7B})U)=;<&D&7M ztF}(u1tDGGxf1fWbsg!~0#F*8i0on1)`?%d8ud;FdRA+s@<2I$carAhz9V)0=42^M(=Jo_rKbnt#h+KR9(s1txSFUfE6qt#hf^j|! zP!Y^IO>DPEv~}3ss}tirxBxagxPR8g%t89gg7Oi+aC6&|*ZmHl_6^srGAbFE6FYY& z^fy|OVTX+J-#I@Y+f>ezExNy8qpW47QJ|sBcl}Q2VKFWoJLp2G@8;9=UC--+fFk&K zu`VujJ;W51=hUz%1r7%;&C)|c6}T})pD{^w>|oJoF+cESVFZz4)0$l5)_rn|VovLc zDzQT;tptVXZ51TP>#vi8Rpn@1w{BMgfaNo-%pkAXrcbl14IGhw+7Pys&!apDj!nj# ze@(hKHFZ`P>L`8nO_4|U=!XWu5LN;Mrg2_*5H2PAorqD&_sL=O`t1y`Ut{^6ILMAd zzH((+EvB)|z)uj0B^q#l6!MZoJV$P_A$AO>IeU>Az3wDPcjM&jTJt<9nVs$pCiiU2 zv!O@maPa(aw?W~F5&`SWv!!uHrA6%)u^5p8u}RcI9s>QO-)b+=yVgR_U%(_V=sgPW z2s$Vhe?vw&#LB2TJk*4PK7LGfj5rm2Bh5z-fm4hFh|JqwhX=64|95}SREzla1BeU8 zD6wyAmcjnt`>xUo=(D9vvLjiZjUk$xb7kGF?3zx!+$u_P--r_MGV2m zu`BDTg1#Lm-kCcwfZSgeY{?Gy^#DHEL8jX{4f$fa4tCXi~`OT%`A)7hxGG+7-6< z`u;|U%9+AxGqYTJry&Jg7GqxUeW}HVhdvKlyg5AiujX{3tUFLBT(sVI&&_cYqkA5&4rPik_Mg=r%vev5(&G%;G~l6M#~1lVrsj zX79fE9Z$9L1HQ|Fz30j1-8;&~&29M3-6A+O$_DlMGU`_>8(%1ajP5G1*zRu2%*U56 z8%ru9c}5$Y@SiPj3?8SeD%jnS*c=sfnE!C>=haE`o2*x6_CJ{DptVc(*T+|?F86=_ zLhj1nR!reEGn|i9U>qD|yQAVd^K$7}YxKIvXmpwe13;S*R1*L5@C3Z@mQe9gO-GcH zyOGbm0N!yJ1Q}@(z70;9g15R@3ST64v||~$%STZ$#v0zkdFn8#DN{gKE)?%H~0g z-)i7Isnc|!KMY$wlJ&21MQ10K6 zQYn;sXo-$Fjje6M1^o8b)8@lxG*aJhU9SkDmVap<7d_;%|6H2-k>khImZrum&BTAZ zXCShx+@SV{-!;J=Szf*7mx&+`(4`jlW`tL>vfg=vY0JrttN%w?or0`8*Ho%mF`-A} zctk@~ivu2%GS$ubTS&jE#+3vR7D0O5_jU>pu#ss?ZrG^3_J>>WpbQONKn5XNG1!9+ zT<~%vGnF#k(5g+P(Uj!f!eY69gvN0{Vrgw{^xuS+jnelOA%#)WV?4? znXCVK1@62$&E|eQZ)1H3`v9kV>h+GS=YN_%2|YX)l;Jm9_1vc)>DT-BR&ewv5e?Bu zdwbt&!ZA_FoxcQiD0@&PF5V&V&D#jJOm%d!x1S<@PIXl{IArJREO#FMQQO+f&*d?? zscE_A{O*s}dL!scZygskg85MsUQa&nAceRfH64@M%(K}V5P}el$~QhB{3dV4_EDlmrhTiVB+CPIv&l25Hhb5R zNcNTDXBvU-U{GENICskP8xfIp?I$_8k~gz`Z{NI|V&He&TBIzq?$R+NnHwxvKPoe1 z$G3NGEgu3iRy-6ZAn{f3nSj{H%}M5-wgS>{G_9t}v(v*_Uc6Q4Qmt_gUXQJp68;=oy%;9A%azKKFL5k+<~lYFyi!rx zfD2(e`iUK9T_Ndg`ihc(DVH~4i`v{r{#)g82XI}=#(KR{0uB75uCdIE56-p%K!p)w zMU9QzKKE((dQl=9D`(xM-f}c$()kMTSWWsj#_YdD*+7Ip;ri6YlpnT6-dYkJqvTFM z_^~ZBQbN3m-R3}qS-7HyE_FB&0mx!Rj?)KLHXi$PlMs>CWO&oyd1IJvUZ`YPo~$^9 zxkPQU2TYUG&&TgFe9a84&YNvxgy)9eu8>$7+fq`}m>cd0x7_c48y#-7sdX&%m3TAH z|Ej~J_B9%H%tJ2h5TISlz_|K6Ct$`C<^Km6<+Udzr9JVVF zlrJ{bvWQ#h`7SSX8*8mH{B>WQ)<#at%w>*{{6@o*56fH#?DiRSw7-ij8a@V?|W z$c_)M@mmqhZEoby4$dXy>z7jx29uDGFe$)RNp6n^iqSJXd3rf4zn0bx3>RkQ@(Jhh z5kteA3%!hV@(E|%VE;l|4V)`fyT)+~eMaIdB=XjpyVzp4T@?^|Q_$9y_5OXNSJu4L z*yjCwLv-B4<0T0YIGR9!GdBpO_&?noAP%OF*6cPU*tk#EpI-u{Ke}!#>v@NEJ^f*! z!K|hH^Pg)+s9oSlkV1ZELWR8JXyy6S(gwp+ji5p_9TN0C{3Zql+es05r^CgS`wt(a ze``2r0~|2x9MB$Ju#J7%hiV@?!lk;JneWS#~>00;&8)KRyNbqhVMLnZj=WsEck=!5kbMBc5n=G^Y zu}6wWiWw2b5`=fs1Sj=_iD*U}%2y{Z4e4k&Ho-C{BA1(a|44&sfTpv4PI^!u!sA)( z3G(kAWIxkW8NQuMsNDU4fdgHGA<0#mkPkfyYnnZl#HuhTg@@2NENF&7keVh^Pj5!v z2N)E})M%T>aWfj~W+l_{ZCCdlgr~^!)ufNP>CN{6!7r6Gua^&c@La-EvHHWuK|Kn# zOaqpf)LmQlV>FM9e*$6(k=3DNKlNx7`R&x33GTr!HBG)Zi>G_kz2*hzJ_iM9mH{s= zT4A9>C6B9>oA2)F{+nulqT%^FfyH@mTmFhUBwE*}r@EJ|A9BV|R+fE#v?c7}IeZV3 zDtH0QX#TZ5p(LD7|LDcs_sDfGL=;VSQ72!j*^H{&r%6FK;=uboXK-*cVFNlZcy)YT< zAXuJ$(#&l!t$wd_z_yq2x$ZM_&6U6QPA+wWyFG8Bhk4>$H#~X+GE|fdslVv_82eXm z-Ra(pX-v-G_`3T9UaiWeXto=xb~P9mT+b^V$|;0uymYZ&6WM32FDqS2!TY&AYtSn)d6+05;O-!3pPAqjFPzjN{>L^mjUazZt%`=6$@@T2wsMriO-{FH zYfsZ|pd1d3e8$pXjve!*_HT zn&*W#rpUl^JJe3uYdCM=RKQ``k8;xfX%i|B-PY}%=+nI;a{kz zC6!Uu_jUrU$Y(`Q_36z?gpRm0NJPD}IxMN*c<`T?_kS+i{G!^Kj;eHAu%C^aHLz06 zTGWOX741-0_&mUX8ab$^b#FqQ{0WPoito}1-j^E}>_CC6CNz`uSXN?V>2Km4_;HN3 zhM8}#MTYzidVs^^QSeH52~(>0PExDxD@EyWDzztB-4!c+pPYrxBtOS{m8=jA+?RWS zcxzL2`)^rkc!J1B)~U|=AX$}Sr&QS(k-{#BI4pG zF07#S%@HI@GAd}r!sxaQL{G(9)oEBb$Z?i>Y6Y2dk(WO5k z!MineMDdl^*Zv}N0)&`CgNQt@p9R}}>aHS~#u!Z4Ijn4_8JxtFU%UUfUg=6~u!`mN zX^u+$mO409-7v#etqy#ehZtci1>8N47PAGMDtM3R{hQFB28_z-i5f%mHMV< zFqmBzrwA?$_wd|O^( zU$9m3%}T4LhKgi86EX3@Nu;tV*z41w`L{IIBq-8z;cGULd{8tyibHK8Be6F$PJ52x zri4IAwI+0#nLBF6t%@KhPMr%^sjabRDO7*3iDzv$a#~zE{Yy;?Ju}<3h$!LdPSxMP ztE_n*N%fviBC{$Wdw$_?SkACpp>G=hUXzHrvM3UT`r|o`VEd1oJ32j!k2Of9lgsO! zU=nBj_L=cjt(l9Q3_8z|S1G6Q9b3Nym@vL@;BIGCE_}AOkPl&#;&>M}Ws$@p@T} z;azxW)n~;LxJ9qcpH;dh#I!dnN?6HJ@GN;mCXnmO zwlEc%oRz&OkeQF*37VF;bna|i>FH~^epe{gIfKQRW#yTF9iSK;bV0r%D5H6LD^#(K z78FyTfPK+_^EI%~^>O2MYAA|lFRmVuId5rdVqK8my$ZTE5lL~ zCf2GR2N*;m4unf*DV26IOlVR-MK9+JG|y$ecyEl}6#;WWsaj`32E&s6z`;QKg922< zx!HbNFS(RvN=uv=aIX@Bn>Sv_i*}AN6p9GEV#4E9IJ2JvLIg@vgU$vCSFfZ39hTxW z2ZTELn19afn$M>v);TPHln9;9Hq0d%F1l5N9L)ykMuF)|NVDTd3|QmTF#aYZO{jw$ zq3o;Y`%S&61o27^K7ldEGvg-Oxj|mVX)cKvtCWQ!0>biR1rc9-7u{KnHvd`Dufcl8 z)!`Kv-Yg9VIZbZbWD)wwxah~#ETA6F$` zD>jZ~#gu(dj^ZIU24SR~#_yzyt8@Usl zSF2#R_3TcwA&+Y#Lagf;(v6e06qcoXGr(@Dyi`^GD@S?E>c;$y)l+Y5S@+XEFYMg$ z-Cmh}9Ynp@FHXSGoK&`rI~!c`toJ6{$$1CrX=VPc2fGFf@7<2IG?z7azpy7;&@nnm zj_cYMQn8+&L8~a=DOCcxYU@yW@r1f$4(TG*lxh%ak{|oP3;Nv{r{mm7&O1mka?r}e zA3v0e+~L0@MIQ5(Ul10yp*N=R{mOZz)Jda`WX1zWlTDH2{tT&z8dn(mi0!VP4kHc+xJzlz#N+e|KjiO5a&6LT|_jH^*>CBMXtGi=7k4qXq@| zS}k!|j<2!VU@P44oRR(S!z9AZpZ(2_1N7>njv>5XwS`~rmw3%6)v zwO8pj>FPH2EpZ^q`!5RIV+LnTij1U*^$}-|jAU&|>-Nv>Cc}|h9M-ozx__;P$>~dc z>SBqsXX{SRdpMe`22p`dqqt!zI?<)7ovVTuFPqV5{<2w2L>c#lWjc#FQ==48)T}XF z`tmDd?8Nb-Al{nzk4?RY_h1M_srX;i?UevWmx%EJ9PGi|uX{WHX?aG~CFU(nMzSYJh%uNSHRAp zR&E^-bdtEOT)R#K z&L#TbU0xs52YA~X&?7KwS~f71=tut}N*aFmlmGC=P+=M#F5li3h|LX>eYq?JD zYBDuzPZTt1r|vj!Ob<4k$1`FmFJ|%kPWs!vA7MXQrz z>^Ala2j5t5<{NaDc50tdEU*k3V89S(>m>5f3)~plR&Ihs*N(eimh_$~=J_7vV(WS- zlEsCot@`d2K|(1*Xih;#Y)(2_=%5>_*W!UpRI7@F-1(Vb#155uyqTyc|W999_L4l4dIj+mWz8%2YstW zvN9Ye#Tn=Q$j3M&2M`O`ez@2Z993c;0Pm@ecuwBx!3>n~D$R@sWTB+E4F{_ z#hdF{=$)MPVBb5sW+lBDs`54niDYXFW+q)N6Dk*DSfpO=0-*T#(|Gdn&;R*-PO}5N zQ#4k`*LApMw=c&sY$)PIY1FEdvHa(yc{FzKS~Dls?Z0w*T}HoEie#TUTE4O1`o^YFh< zQUt?#F~ZbP$ToO2Zu*^@g2%$~7Bfti34DE!)4!YzlAaug=;*<^n<#5d}J#^Lt-f1c+GI8_69hr~(CVFTLJI;*)H-(?N zC=1CIWA%iilb2`X_t_d&j`OsU>MgA5LNBPs^7tP}XNyVOW3)^PNGMJ5(b{JyOIm&O zyz?0+3idpBLHY{y(YiBftPSply4hbLykW7!BtP8s?i6ZT@lfELwhI)oT_zB+V zL3xfl+(FHegt_-3POP z67}LW9)bbwOVHKMt_aLKt!VzS&*)o15O6wlT{_~~Cq(+?Z0R3jcxG7g_(ORGKk+U` zm~2#u5Rrpha6Rz%B07nqr!#*C`M2F_!#N)rC-8Bm4(Y{B3U2s@T{stY5uN6MB(7kk zUZs-Ruf74bR=9u1@56w*uP>^C6gUZxTi4FWf0|0N|3v6@Gm|ALi^ya7qXx4S)@eq@ z)xbNOeV@6h*iw^LGMz4~5UsABEz(v7{zQvnbT=^{u{5B&FR?X20t=uluwQV=>h`DM z&&soQNOemh|uU8B8Bi0B2NeZW;{NP5NOSgJ!x*Wn0%LVeQa9Dh20!PDU7*>$4x-t zWr$}UN@J;gbPO^HimWc!cIN0Dn%ty#~;T=xgvZ1^T-k0)l8pIhOE2|q>Y=`-vb(DZYzoYol z#hL2cIg2oI;+HqwNXble&zX_uj0%;DR}4Go^G_Z@3hgm$+=YV-_%l{r0Rqa8O&r`l z!qGBCZ>eTezXP_Q+kFD_a&&v-qJb53txtjzf)KvauaH34Y3aj_6fi?cE+XdMqqFd4 z6HoYE;fzmQ7KIB2N0r>zlHx%M8Ojas1LCG1Tb9o+UnO$kw4}3rTd-ET!jS0#k-{NY z!UH(>AKvNop^82xJF!98>Q#y;{Bwv)QYkaQw36#++!l`u$&zWyQ{}bWrmZ z*He=CwVWgWb;f5he`wiQx!KKo0Rr2>D3VRVaUIr0qS|jX9Wu{sd5*Mizr4^sl9R8G zWug>D5u3D%Pxr8mYcKA_O^{?mCeFxaZstq*kv0mUfI-pZ_PKQIba$hsLdvHa(XuG5 zf)CHO^u*W9xysA}>vr$BlZxRXAR3?5n;wQoDWjB0MQHK>_Ok%8)hoJK=+;>y@y&oI3k z^xix!aEaDnx?ea)P}mQT)6RvkD!tko^x0prp-GzlTN3?=*!u*<^IfN{eoSs~YoWg0 zA&1!=tz#z$G*Sy926JAyDBPhQqJQK_JN~n^UD@3Gnim}_&6S+KSym9Lz8BA>Kb<#y zGaR;Z906Bj#q*Xx2aIhw>^k*Cz05HA1o{W!1-?6WcaVSlQn!krvK?Js!gtch zPGXKK8-GOvDvo{gxexwXG>JVozbzxVAJLBvU2#~;lLrWOd}Aa{RKdU^>!BPsvtel` zkGVP7Mvo19!M$y*RqcvN(NUmU<$JiAIMlsXTB=c=Jq0i3F)JN@Yufi$*V$oypo{8e zoXFvMWSxa;MD8$s6$SbQRai1vrLkcCw1i_PM-S$XZ@+=G1$A>d@$gwV&7iM# z82Mw1SpNB9M1jE;ig{-IQm2ZXvaN#e#s`0Ni8@zjenMs*M3lxWtTPQR-A5ysMUXvB z?eM~>FH00P_)CumJiJef%lmF}OZ{l?b(ATV z12`)twD!Y;hzx%DOownb!i!owAlL3NnNnC>XRz6T`vWv;{Mtc&Ts3G6i)&Qz{ChKR zjS&%2lVCMROgWzc9)(WQbdw>_!>nFwf+p5rJJH>%7$l0Rr67X!e}W%W=1|CAGSV`| zhBe~8x1Dnr`N?(a`*CM&t?4$j2!{TQL@E2_no#oRG7i+E^D8bpV~kZ}gOCPHHsf;7 zPX5n=T04|~xR7!_S5j;-^ zvz0vKB?|;=$eSzX@U=*IdgVvX?LKFjKDxhRIy=(Af&^ciISjDz?-|NA%!)U*$l`h{ z3L6Y16Ij?nm4d%Ly#~zd;2u6rMdOy-h>MS(LVLjSa`}UIZl3D?dkX-<4e%EDEVjm) zn<+cwW{r~*YvoW^>xJTWDz;%v>|K{_ukVJ+2;ip?1S}7Xb*WX>!Gcx8IwX2|?nVBvC{M0qA4WvYxU)6R`jLnQJUU_IT^Q#PX=pA z+04yd&DSTi6ozZqq2QxeYaNS`o}I9v(C9A;WDRXLAWId@Te=UjL%;F>|2Q)b(^d&+ z8Ks}vSs9*1TBYe&fCVEZQI-&bc1RXPOPKatj+>4pvTC&9SEveEk#LPo`NVF1bS275 z$&?uKg~VzQMVWdNY_oWR&s_?)o_JB=442d!j^RS>(QdfF5^7T}k=cyB+H`h!`O)m0 z6|U7p{wM#WDwRjxhGH5s>2?F`p^WtTF$OYLOSeIWrwv)D412{DRB+jb6{QRGx!?48 zzSz2#lj5=b{TTREBf$5`zpnZMksr;rsnfVHO?3*~HLeGkt3DcO>aW0OTJpAt#4ao41eIj&; zS8PvJ=W4(-kw~w=LNljtRpt#bqb4(&$^Hr8xbGBj^G(M2b~X@KC1PvQM2$8}SbpU5nHi@4XFdx5IEVYQ4%^>_es2uqCMn#tSTQAu;&Rq;TufKWBC|as?RrumB)~c^2CgiIN>QKDvbWKc|emxeBqqY-s5b zV2s)b$JO{|uZda#>RESe->^bqU4zv%Ipnf|Qd@{2H^(v9Be)DRE1r#-Hd6lZ(^&`6 zG@Whlj(t{|_GCml)X7T?mz*JAc<_4K}!q&oeI|`!WIE z(NGSTz?>WE7(RBGgAWyeW5l(I>xox2Vxu>QL- z_75Bdug1f1*wuT}PINbv4&9n0*0^(IO3g4C*0Tg)jW>IF*v>Zl@Hd245LjyoM@<(1 z1B*G|4@ej}RaI(!2ey7WD@Kz0Og1()`W1s)KdP9!HsJngNQDK8D&BQig->i`VPv!u zM1ssmn$G;t;D|p+jxENno#Yc_FI_G5#oErDsZJp?6A^dZCB~v8IJS%)JBYloc36&flo46?Tu%V=S$=G9HZdT_9H=%0;+Jg}k+Omx z@a7R@Cl<@t&L*^AM}FYJs~tfj*TA8}y%27=y~Smwz_U0SJx<6$)@KTY%-0OdmJ?Oy zfQZy%>-i9E{8{Rnd|#ibKB6@lF86T*xWH%`;2o%KR(&0@fzst>lMVeYb*8B&&vWYG z@_cV$8CMBQIJFG~yy zm$n6o@ASEGc4vEz9F6T70d&O#L{742AA9-qbHOCuZa2R5NGE@5KTv#hd_+iqd*xw7 zO1?g4;yg^_R#r2$ahLgZ@c`JHp-F~%o7R9~5rlN3YJku^HCVlkbY&O1w{!eB1QCir zX3K>W-(xo9>sb%AA#|b6{y3q^vL*2JkSZW%@-j-_4G;&>(cYQGDD8dx%@zQ(fI>2}05&)u zE5S;o(s|~Da=gT>ogNV+yf?z^c^`18?s2H_Tv=eIIgs`Kt0>l zF)>_E&2Kt{3_~|9wU0+95Gts*EaS}`VBi+s;5z)yCtZWN-3e}keYu}Pe5vad3>vtK z!WOB`bwkc96{+LCA0JP2_P`}b&Ju!4C8aHUq{sz-EG&<0LQ15?vmDGXR5Zozuq6Vy zwfimc>q`=*S0^4}oUJH78$W_|k;3?DZLk5A4$*&WASRg_MHcXC$;Qcc+Kog~%hd&y z;@9=yPl;>CPGYR>!fPE+Xlg%qpueB<9_Bz0Zdk;~?TIK89C9r=+#W>g24Ha5Y?E2O zN2-$|A6SsFMER{bu1V>rv<^*uGU%OHNU=Y-=88=$kd-R9F=eNDt@W)NqEH^vP}U&F zTR$9(o(tw)y;6c{wVAcT!~dyIDq7B`aWLFaW0fYRu;uh6N^u-GYflQwipDfb#DQ~cIHsexv1%XP=$61 z1~k_HeBt?ovOm6m5LB_CkaB-?es#t`FX^tRCidj~ww>%@UPvJ?H1O%o2eKP+B;{)7 za~36$lu9z2z6e3vV^G{$#1aWS?C|u zbpih5k^8TRwjZOIB{PhZKEjUS+7)ShpnXa;j(c*ve92345~D}vV&FZCV8egUBwC)Y z8f@IN7j@Z+^8tnEY=^eFCOj?LIMjf?{W5WrG5L_Ec$=|fCZz~I3$Fy1IX_vbSs}_w zGY2&Waxt5!@vJ*NUeK&s)r&WRewCd<$}!pQsu5{j7Z1;l6_LF99hvD&)O!D=tE$zN zEfZQZ&u}W=C4XpcM5?imtwB24ZM?;>mVv-%7y2*pDoZ-2>o)LyuBDWiVNj`P7*5bd zgU)>iB(F2(1t#RPk{pu-qr=fQt8au8rwv0nG1;- zL~?-{twr*d4Ztt&Vu8rgx7ueKmXb>E^{_@`ZwhvjY;9G`|sb^MTB^Lguw=|^rtH4KUaSi}>9%a&mM-a4qM6^ZtY7qM3C z(cWu#>7-u2`!;I|gp#8<5%bWa=b=IiaNf3KFJ8AMv9C)UljiZ55_xt40!_^~+Sl2! zLeD^PjXs(UK_{J#5iuU@g#i%-Y($Z4i9{F6TK_dLCGuO5Z&bNuUj2}m_vm5Am(h&< zdZ%W8@S>}QSXe4-$*G+@9-FXO)#LNAZ=4p5GbdG2&-!1qwdOV50@VCimZ9whRu3HIB@3Ifh`YxD4?=swXXV*GQzs4qmW4SgYmU&%aF(W1l7BWn@cR9r8 z7_)f8tKJ?*RX8cqjXs`D1aA0O@aXDv^%v@Vxne}a7p=p&@g-C8)%`JUK5X8&=gbb+ z`(o>cMD3_i@t*-*DtqxUhxsE}Q1%8??J$9{kvtkS(a|nC!c0oNVKdLngf`5Sf0SIl z1uQSO0bZHf+6tdZB%88>*R=YzBBn<3iex+1;!p+}K6IWb8DD#m=7%?1kUuxao0CFU zEZ%og_Iu4kySiBYR!@tCGusnQFltw+I`8dH9rvnnvohTu#oO&@_p&4H z^msSic+&C1857dTAC$Aq>Hc0S92F#)afZ1Th0SMuMa|_Sr(b|qoMeH)B#pFPxr`WI zNFEUH94P~=<-5Py*3|9_xRF_GHH%wxnr7TLan!8u-O@*aJbbx(pD_qLRw15x#!Ig8 zBgGk!hhBe~K-y|Tl1V+bIMg_1V{}r59NzEboxcw~a9sw_yt1PS|7Fd)X1@)(tF*NS zA&QwQtsKy}y{Hq--b8cEo*|*;SzLBnj4decO!ydUwhk@D1)?#aNp~pL^-IZzs-R*+ zKSRdaa5ed?_(U8vmwiZ~J_WQ3hT=E+>aO--zQ+*k+PCMmF%JKOf4D=y=Ic)IQTwM1 z#lbEMEbvI^xieiML2v$0nv{!pc#C88L5OCBcfT=-9JfHXvrUgyqoC+6v5E~6g(BRK zYdLDS%L#23pw@7A6Wt%=Zqlv{=~+Yj>e^)+4YhN!^Gb14j1gyqCWAk|v%E zdZ>S!JEE*Sy$G|jw(mJ+pQU~(W9z$h)n&OuP0F$;x3M!9HpCVH^-}qic)DKIm-d;6 zsz_ZVd_+~Ih+O)IX0#HEH|*jItn9P z{hAj|uJ5j6A~9cborFO$vW`GMXewN_N&w+`Mu}~tjKSLu&rx>!^ET$YB=$p@?^v@YIRN(^g#}Zt@lJAuba|F-FKPff{F!uswr03=};$xRq&Qx--vcm4T z)5dsyizX8<;eid;D4q8#LMA`YD10}=zFJ3X|6x~eU ziYWpp#Foz+l|XDmkaL68qC*|KMrm`;)0B$PG(e6l>F7upTX?cs@T8_rO1l2L6KpqX zRavYtWWqdKJDedPYDM^(AP{|dKOZga=DcZOQ!JYV;7FFA<(7J*L7tN_|){A}@H-5;S%bStvt>17%V zmeP4{ot9F>V@g8PQ;DVxo}!iz-T)NnUN8E4o(!5EyFW^ezwC#9vx`%qRd287?AUS= zk5q3Os0(`06rv~z{=56SiAv>! z#KbU?7zn-`@X1uyXFeOt{n8oE~MK>{u zOt+KNyT6ZHGs4~-)ypDl{Xnpm@o-e}dn&wG|bM1~6$&%}nPltvs+9bOgNLhqK+BJ;Z5hOV6MFq$S12OFJG+L>uLow~thMXBw*ck5wgeZQ9Xf$X1qMPwzg_)z?q z5oD*YD+)u(Jeu)EBXqUC$`4W8Oxeu~k;9PCWly0D(p6oiRhu6*G)35loEz4sYRM2d!g0N61(OsMLIQb7@-cwpc;VL^lg*sUf zxmi1;1Hl&0((Q?Sl`6w#bWL4Zld-v2Qv;`!a5Bv8^joN=Tq9Aa<3zMrz6Ho`9dh-& zygSzNpsWHmbouj+7iA{*G%l}fL)H4E(TIJ1eznK$lcH~2rs<$unf=od8o3M^IoShM zsc`kdJCAc@1L;s2>m@2Ah{LMFeCnLsgWNWQaW9`1rwp2K=cAfA3bR|MswJ*+G1HITd9+9LaYF zdEDM2xq589Z=b8}rpITFd;J`G1QN`O8ycK&nT*H=X_P7Ci?4SnX2z@e%Qyc86pOHi+7SRaOP*(HoeMC<~=B@0L8X zPe|vuFDAlJ?|iJn;$omXR&QwzOA9H0%8@zEz9Lc0clnw8>9;%a{@MsLsKfqT_(^!tcH28_f@bbnFr zP~x8Xt?lOlaie9;TF2vo*|(4QY!09AVRu!3bh$suF%Teqx`x7`g!LqLFRPuc3WyD4 zHT3X+=c|hO4++w)N3bO+WzqALl$6x44i{@QweCvaZS0X;{S-<;#2RUoIB<|v01(rE zHi6qS3EwZfj|-He@)pb073=`H1ZWt`kpq4RJUC{`#N|?0AbrGQB~@{ECri}SX18CQ z{)}bvOqp(RkF70{FGB2+->hpsuVq<$X!{!QSyIbkMVtR1kcXcyFTwclp=(fTqkbSCwF?{x=H;=uX<{C!*y0; z-up{&@Xi_j>6-$uT%N{Pe~t*xbVvi>q+xC{MelOq?dZAHFi>(`ce#2>sg z)&$H8QZ?_6Z8yW@bYskmz8wd<(f%i6Ox`P)O`!tZx$QH&-z~9m*Z-9O?eBS9VyY;G zGCFW^N_uQP5NK1+jty*+M+RD@U0c{TuTKGomXXW7#F zkm*FdcydGPY~{5LAVCQ~g~HT|m#ZDm1;LI+F-RL*<5|;*d_jS7ahC>- zn~A}zNzl*YT%ek5>Diioc7n@2YLn;G$T_o7kEfojwQu09W*%<6rcmfN%ZP_Bb#?5; z4lB~gBt}49daY~Hh_T9#%5;)%)LbR83iCM<68IOR0jb?8zn=jJ>@dCC!(g1rkNzoI zkD4tVj>VXRNt>itAUKLOz+m%)HnvS7>0uCI0U(StK5Z zFW=uge<<#*{Nadv9Jpy4=j`F#u;c5>s?wsZe-~(+(a^A%cZ>2T4gu6 zZi<(!yAyj;N_+0W2_)>lVH)&U=p7caE8btgN%jT&95sCzZB0oSfVXEHVb3%Ja+&*3 zo-LNzSRi@yI){9BE=g#xZBv~l8)e4y{pU5~Iv>ZZ9GTKXtE*#VGOYSb$w;Pv>%oyk z0-Gryqj}<$HQCrF>wM99Nf;ok{PU{g1=ub^+}F@-!Nxu8WHZt2P;!4#bUalcus`Tn zYM|!p{`i2tl|qLU5z4@NWZ$EpvJHR^^gm4aPoIJoAbXc!Mj{0-d=!hfk8+D&9UaOBw-+ATMTx<@{LYB9F z2f9I-sH~l{kByJpIeRN9p##akuj|1W$mGnmQ|kJRd)Jkvr8^JsmmQB3_pk(!c2W*E ze7oUWOu@#k9;YW($Gh@;Ij=-d$bTQ2yNjl=J^GNli)DFIzRS7{vtu0sm8l<^aKTqx zu9;@_w$b?`r1p$)?BRVK!K=T0Acj!;P37GkiU{f;5$4lZzLNQG=pzZa#>1Un!Tv1r zeIJd#+R1XRk*+%#aNZKK$!M491eAqj>>V8)2dH{Lf`({NT?xDz!|W6s3(S*$yQe0f z?AEx*YkxPy`?Xog;8+Kul3I)%ggn|}9+*_M?XXlbI4g!}wc=aOD7l#PRb&W9PPaQZ zc^Trd^XN3Jofi(+rn%?{BA-a+C-(Sfwo2*hG5F(Ip1Ai?Qi~HYwQpN0Aj$Ilss8U* zm|`y_0;RM@s{_t|fcv}6S37&Gern3>*&B{ZF}x+UyIg~b87NbMSz_j(1i5^;@JZXl ziV$Lp4sBgk9BiBeAkK4S_w~ejI=(-UXDe8+vzb8RF1_6(AA*;FjqAff;o2GG` zTf?b>Uz!-(DZ!q72D3Dr)?Y}V?E zVdQ~kQyCjdeT|?sEFe(u@p%;~2$e_@Xvx&F&A$v{033o0@cF8sdA9S%XvVq}Lbs#K zyFKsh!&*6M>3qp}3T4g;5YAS=_7Jvg1UBQpx_u^#I9(ML5$R+v`C7y-WivAh-kZzf zqc9+9wY=&Lh-({FHL2I+GL|i#7xe(X5|@WFuF9eRz2r?bzXW8abpP9Z1W8aMLMKnr za3tdd)-&&3!U5-D+almrw>E5B$;-BOQFulbw&1>#H2MR-VzNM#6l1vePK6WnSnEqL zDe7C-)$5au>LGE`Lw!7(XV!Hg;AK#%%Hof%oS4j>jwwBsTns`yO5-$^u@PQ|&vGe5 z_MM3N>bcdf8dzE*kI>M_t)Rrbkh6OUIseCNRRt)MM^29Un+z*ox~hsU*5Dct@IebV zt<9sQ0|soHfl?Op_lDG{XF?9XB;Uckm*+&lpZnbq`&T9WYTyFj$dzTo8qmW=;72 zrSXAafuTq(kmo11s@#!ogyW$eQ9WPl;-T+xjMIghmj>{CnX3UXhMB(Zv$bK^VPj+C z&n}=s-o2h28L`3H0ys^C`XONH1cIln z-9r8JW=is{t&D;|U=MA7*{r3ve_K z+`^Yi2Bb62INJpUv$&))&ldkL0sNg@KbkYyKCT%Iyd6nqqmVyA!giaft+o9MBX(AU z!eCL6rx)gZ?z*P`jSFQnVd|@`L9u()pnJGEfOpaBdyj23Q!i1^RJNM+N;xdkE>@H? zthlt0*McfhILws=uO!vr@|M;(mbD--!dfOk@p?iDI1%r$zk{$}`ph9sp0v8Ii-DCF zYaOnny3Uh>^xa$FS6L6Q-S+Q3dP*2xY9mvbJV%Ae+4-r#Q$;{-hweyblEW?q~yL&?DQH-`nx@Biz7)*)^J{WgpD$D?sL*?FFW^u7`Ru zdfCN`PgC!27^`j0EQ8$o9$eX7I!|1Mg@y6Tp-H(sM!AP5Ls*BJziOG4j9=Gpfn0+N zBb(;(TbloWI&z-B*Kq;kqNytcIB)*3qYpdWb}gWC`}*pLG!It8v+?tm$m5TsgX&fpnX3jBUU03s0nZVBsHFdUHS5_CFq?M%*YX5hMhzWFKvFbamb?!Mo_1Vs?=_}Ry8(=xnij+`)^d&DLuA6r{BUmn<`Ou=b4jvsw{4e9XCesmT0ye>DU? zPjfs!aBl5)kM`{{to9jQp>v^J(dA;mZ7iUy4Uf@+5Gy{^{1`G^n@9+h4WtHZredzB zJ7yRU#s7E(Ibm2Lsv~+vPd>wwQeX-kvw2$ck$m`M@)(ePzSzy|A<(jR;RlN;l6y8- zaJtrNFoqc74GDzXqD}d`h=KdiGQjSHF%f*e=$j>1>V|CDH?Q9>RK1B$9t0s6Ik~F` zNvJoCZB1SV<3vt;b>|;H=@DF??XRHtd=0N`P+Wz}W*aK?ZR)gtXtD+g%^LVx@l~(8 z^UbyU8j(030VIcH`b_cv7LSqtl{}c z+I%QzT-;z5BJ|SSS@|J?P}UMLami3m4x$|4bY*nOe58aNp$O*3oGrX8rHkta=`{n@ zPrv2Opk%^C%SobNa#wdvYX|3ojehkokckX1K%`#OEs5Z_7|0qRff){<>{Y<;_QIhA zBy=+Q6}3`VZ|(15@??g(MRX(e+B)vOq8wY{`z+6XLvQu=*_s#064NhUgL2&RRY7KR zou!&v+cEafj(*>S$*veBGQ){>Bh*UY{`>ia<>7ux<{Ra9Z6M>5)BRru6e$#ZaXSpv zin`cl`}cTa3SfxaeE_i5Dvh1ydxSi@spq$W?qM zLHk%`jzE~kOCRW*U!ty08r@-m0~cHTIXGzr3riQ&>A2_L2<8MfB%ZV;!mN%|wYu;K z29Psh&zE`Sj)yas<#6o-^1yP;BOdaVHogq2g{@!o0=p4mqH*Jz!t3MBRSzNX1|b<} zZyb30D1A>}^bd%rkn$qvrQiU?D|YO<&C;IKA7V2M>bw9P-h0ec(=3Z-4(eFEAAPFM z63&ao77QM6a-@*uQCT4Xu`70u%tB-V3$?ePkQFHJ&HwsWL7F_jY82QLN^O;HncP(f zjW1(F^cQOyeJ2OR5J=oS{)%CUYf@kKC6ERfRvr|PK3B2wv*lhiyrc$&pKGC4ZiLu* zZE}d4v;Js>g9PeHprPM$^Y7D(RHR64bPs5v z1fdd<2!f9e<2nPP9vJY+;<{SyARmJ)_6=$3K-@Kf4Q&_Flg332COr3ASfreG8oX__>S=E}!UB$YC5uo;PD)1~Vaf&)~w z%EsAAsMm{Ped*bm?7W$|+llyWI7{*lnT*een}ubl<31U-y8y(QBGYI7>u*&Smxtnd zTqo)HSP>i@8a=lSO+DOu7M=Ix0LLR*N6~wdwuhXa_BI$CtIonnD+s4g9*`4yNENXo>huyk?icH#1JUY++GJ3dDS2WWf~m++sS`PuD!+vd)-hE7d6;T`M}CFGt51-Ah~$ zi~Bo<1ZW>o&5|4W_zq@ft=4{-P7F)nSb5QB|4fh1E7GSliUDa5i-n!$+)P0da1W%T zGy5JC92Q1@mO-*u@d=3ZQ_xISVFcZx>=f)Ri22Yc&d4X$9m`7LQme)Ma#Gy|C?rv& zw4lyfq39)I@?A9_7WBS=#MS?*@UJcvs0tUpw#+(u@6)-3Ck|jk>YcA6o-_)`Vad)1 zNZnE!D5HBjl^^J*Ek(rsbeLj)HpE%dg!EzMcxcCGF+MT{F5WA5^$9)0Xi?digNWPw zE;>A*$fz^v)|0k_`oMD=c5mHa&T5Qkh1Eq3f>@8wC<#hXE{}}rj^>G;fz;L%LA4ZO zKqm|NhSg`eahBGyT!k1eB=YkteLHyjTMhcl@#a9g2x4uxpH?)C&==;ne7X-1&ZXq! z?-xw6H?Oa7h9*4{aHxe>xW&QY9DbLVHO`)hB;!VrGQXLThqz%U?O{38zoB&WAaB+D zTz=({3m)eC`1^~7i!9*~!7a#;YTNXtA=%x176gVEwwV!?954n z9%rpMrNTU}R#Jba?V+$Kw4gGq584Z?FR|lhO;0R2ID&&|_;p&pb9U_8P!&9D=+4)()9-INQP(3NkxC5HDSyc?lYqq5BG1rNm`3q@6C6k~eX3i9Cra zc5s+{`$r@D7a^sbN z9?EZCLy}P!>X#q=BNr^V;F`UN_P3nqxv=opfA-}UdQguE^dfQic?v%qf&#Y-@#%{+ zeP1t7+KN}Js_^f&iwy0cztl2tbgGB}igYWw$!D4oZn+@zhM95dPf}(QF?mEv(NmPa z=r%RPHhOF3sUk<7wHKhs<^H{_ps&i{XHE$-E})^D?E%~LwI(xD_JeG^zu3*3pg(@; zfQ#Ck+GQQdhU{*&LS8A18r!pgZ+-J9Z>BiG;5yp4RpIA^+_-cvee8X+pL2;n!XAdN zrnv^D8*Fp$l%g1dZF%@y!Ca&D#ySFhHyLKjQP}#+~rWjC+T2U7#w#}1E`e==c)j37nd zc%9P=KdeX}@^JRr0OQ|5hanvS20`Re7Eeja#)p<=Gg}(NJCsa&N z^v({?*3GjI|11ztKNckY0}6ie3^fEP&Lg%S#aT+v*513#`Ckm!N>v^*^?v-^Q%rw3 zmtDD&6+8nQCS0n?PJBDD84+`v2{fe7L4?pCh&mAzycDVWUR0G(9UEWZ*OE8Oebsl$ z;n+uuvbt>!f9B)AXjf|BdluE%e;K;wab$UqhWrrq+)%&MMZQ;hu5+9&RB@8~hHT$d zX5>t_wOtmtFqwm2E#vz0A;8d)wT`O(G+dMCitXB?dkFDjV?nJx-jc0IBTk~0WrNrrD^`>{HYcKGwdKdij0wv?c*X?4GgjE>Xlo8Ta*Y? ztnW~-)0QXuU_jy_wEKIvabyQmuvkw<)}mt`P~ByLMA;##aTLi!31~%BZtrd|yLCV7 zEopH?O`gpqT&sUIOiE|0`P;sBsW1Be+03gVqmT?w<`_F7N3Hh(f1@#tuOH=y;R2Jto^9^Y^j_Dp_C8^JxYhzN7oUr$| zTt<@x2KXj-`^(Jt}am0M7`nZ_U5|o{Iw&A)$m5eL5(liC|^wu7^GQMS?Fu0K72G6 zeYj`D#HFfpOF!#h(4iMHhcOlrWbH)T8W;70+$W;spq40%li{3NL+gyHqd?8CV?DTR zh1jisF@4@0NbjhVOOd%^Utwc*;CxE(Kgg@sr75}dv|vgtij^xZrV(Bxy}HD4TC)R<{I-Aj4cn+r7NCzm!f_E ztf0DM5GmpKoEgH*LydWQp{f(B1Z9mnY!MMZPCC1%1+GBH6-`C%<9(3Mn61ag{l}6g4%OT)=I1^DE9$K#r%o5yR;5tIV8Nj4jxe3qLLpe-_X>z7FS5C>CN_mxsSTv};%u zxSAOQP(Nv__Afm|bfDi&ou^I)D_5C3e?JAfy4bXfcT`>W>op?Cpj9I*xsd#Pud1{_ z0jB-UgJKOa3`Mir4|M zB;Sy3>d>;N%ITS}MQE$no}5fhLsk6cEQ+PKE}x=P597|i6(Zz6pG1((R5QtJ?TYiU zPk)Oc2{Pcb?-E64D9f}`;cMr+ezs^%u1%L>URPYsD;~3$1YZWSnSSYkl8K+Dh0=o} z#Nlb&dFKKWoSpbSGV;(xX0Xp)2ZsqQbs*5bP(5=!HTs?~hvFYW%~shLktsd6u&R_- z+ec?zU>q#$o3pPJOYNyCxXER4njlqfd{?(Nhj$)Zd&v7@sC1`%24=fsSB`NX%65F> zAvrmF3q&=?4a=zCe>bm9YWM&(URMQ53PaVfrk=)b)W3-eBx~y~*bz~A%uJh@*b96! z^mYLHMkDsvM~}VE0XG1Z$M7pbTaul?SrITv{`LF-Y^}h&zF6nYTzg4h;*e(;sZ{^|i-+V0y;{nK#L_3RljVzkGIW%-%Z=OF?FBynW zRN*#i+HArB(CQEZ$_e<{7eVRp<|h$YqQ7(&AhTavXe8)Ghy_g_9#lUmwd`~!x&*BR z3PPt^&XU6lZ~lvC?T3vz@nH>^XW`<;E$G=JG*p!B2ttn>RhXRngBp?007=gdv*NBs z zz8QTeZH%$wi`AB?-*|JseB@^o9+cHg zt8)HOi9`dpB77@|RGce*HuCJlCxndcjK3P4CwfCQg%4gcsO%s)Z3(Gv3t}FTXz5)| zg|aHAAd=Lsu0Em$sZpC4&j`DE)zbuuXq7jt)-?a8+-e5l zipr`X-wOs{DoW}W2Pwi?60)!JZbU7s5pGW5Dsa-5F2i91c zA6j#bLTNe~@}R?4=l#{H7;Lf9smyTJN@&g&%~dclw(r}YHaVR7+jVZPVm^(AnmOfy zL+gQ>J7oh=X7k|$iBZ0BuDR4ogaF=kjlKV;yZIsTCb3hv9m!I7(S4cBymyrz%D~8h zLUCqN^iNrWlALam1N)GQ{w7F?r>@KV-heWMd_KwO$jGi0H)@TV#GgsK* zY7A_&S6VKV1%I<0dnNvTa0;OjgK5opUtlH}6y4?u=swt~n=iAY=^r{BJnR*rH)lvm zSg&`Q<{&PvP}&t3%(rp;w7usI$iyWN(z7O6)fcYKDY!!@+R@943e(Pu zY&BMZMPxa8c4a@m8y=Z9I}Uo2b}P)y1WolEJlt4}ieEpPi^8mF$9E2 zHQo|AT3I$z&ccTk!Dm1B=HPSQ$0$&CQK!L_Zi+DqQK0|QY_|G_i)*ig++s=KU6dY5 zJ?fM{6{I%C9S4i|Qx8Vqmjy92eIIg6hGB^K3`2I2GEo~MC@J0GU!ub|u+`|kXCWsP z@LwiYTaN+OPDue>#)R3IY{L=ML^Q4`hs(n_zgP3 z3%6WlN3ujyte!J=Vzo)Av#g~lcJS-)RZm6HCfYIsp&Ss`!5MnAXN4B7OlipSofebr zW9AnFw)E)SpJUmgtm)(*q;eB`KB!1-8Rmc;K0$MVQCBAHYTRFM84U>Ul`+o?_9lR( zqJrT<(yUYjM@P>#r|<-KSlr>_nN;*<8!srm>trX` za^lvrU-C^&J?*XDQwlivzeu#I@{CK4Hlbn~uxPe&$)Fy|_fL2&Pg0p_LZ!N<)bWvi zUoQzs6xttCv&6z1tGjSA#wR<7l39x6$o8?8{tCtI1e`7Ux^@?^!u1b9WL2!4=Go<+ zK3I_C*d;5-jjd}lru{N(m?h^nV;eQhj+C?L^?p8WyB2jmM!TR@@NeZ1_xhncCt&WAhzVA3EqjDh& zDHql0Qdo5=nBDi!79IK4nH|Xbv0JEpvUw-lC@J?t{`ObZ{!HD4->y!QfM%&AftJg=i1`x0;`$Vb@q!#}acREH7_y%64H%hcG9=O)88VcaQ{wc2-_`$ah zT}azRIU5bM zN|wk>9N39n_`1a5LHziB1O4i|3EobRY&cfj4YRC+3TRE+ z@4KaLQz0XrG~&gY-$cJ7V^qb~T}p^zT{Bq>1!=N?k375m zTkSfJ)6pLq5x387d{CSS*1Agk#NmvIqc2o|@ck1E%)!hE4i-SBiB`cR5Iw>xGb=}j zGyFmYh?i!VEq8*ez67^VOpZUH+B-#BFi%g;hAHWQQ`tGBP-2W*5l~D}88xua=BN|R zcG9Zt<$q1DIz-r*BUrRsL#w*Gb@jOJ0kWnSx1hqc`OMgfXbvsPFI}Zy|7@Rkdv9D= z_U0l|7|bXqjAOU90Wum|?ijCcn~z-0k(2-BHmT}P17)oHS5oJL1s7d=qPi2me4Uis zFVAVz$o{ez4oW4l>+?2*{v(bext-7rGuqbEIP<@mXCz7&5dmlxrFnp&^HQ%U zH4`EF@!A-?=1K@B^E%|{vu@ZIGhex`UNFsK&)JELQ%LrdQahn2$=-h`PO*+O$>X|@H`LU|FFJ*aX+Ns4yK=~{%C9l%t3=}cr;iIf^Q*=CzlKDR2{w}@6` zY=?1GL8MwA|9H(YZb}%T?ZGuHbylw?@f*?-LNFS~h`e}k_0dm`=@qy}mv6230FM+~ zl9tOfT0KbXyLT@u>DtJ(b{9Fg@jYhib+a`uLRR7T1Tp3rgO%-+9}jOhhtL9h>ru}- zro*owbfgANtk476nxa~6yh6DurJY3h8-xiMomnFHb$0KY)aQvw8Iu(^gDpmo` zhL6PEUX`^`tge1r@2m~DJi>5*tm3Te6drKDn4c3wHk?4b@oe*Z?sv&897DF7OLA*+ zx;uSEn91eAuxub|r*`$%)Z!Yq%>iWTiku;%tCnVw<&B2}coqi)l!oGgR7=T`MOu;t zpixruBq<)smL}W94j)!ntW3mTJy^C#Oa>Z7KNPp;?OTJ}ps(a-)?RI`1@+wVZ#Y=i zU!w^qG~V(Bk2yCmdf94aWA!681PNllkz|pWV$22xK$k78Bx^SZ%g zO9*Apo3?GH4j|Ikdbn-%T_bCoj}I2>L6m&#doCrB!20n(wgfrQ+jw7;28b-LX(Zb}E!LMa%$R{oI-pgcARe@O&u*RHtag`_?DX|^ zQg&+JL1sqy{w4i=UM{IA{^FSHRb=dz>D$)I956)^zt_b<`TG}nVIPB)I6@@bo$EE~ z5sEkQdz#_8$LkAPt}a}u_4IYWTP!2Ks6UJa)OJ<8b_A=?>=ab7W$ISzhnG6AlvX?Z z@p1RgJ9J^MSTEg`O+7g{$7Cl z39ZW1IY}HRV7C+r1`L?XJ`EmdrjapDbA;#plaN=F5VP1I?Mdk5V@^o?qodKE1tne& zF*B(WoEygK)uC$l^6@2Mczd_io8jFQ9`XbBiFb^z*V(xx9lwl%!u&_k?4LxK7j_3I zE*lZ9Hp*%QIjgVbJEUOmWx>~BF-M3c1Pa~%YA{$B7bUXz&aJ)<}48KdfAlN9+Pvf@v z8yApG(@CKll`!9Ol2@C4JrbM)Oig>&!c6*-KogiqSVe=cPN@@6U7nU``vAYJuBT}G zOm!YrTGb24ue|SWKH8R0P~eY>qzOy2dj(NJ5&-Jak)yTV9dN>vhQIF^&k>yc4Ye5I zd^|UOv?1TrNa!%#(k9Jt?3Bf88Or;QOZmT6&?s|G7@px1!JkqF32AlO@}tvOlUr)Y zNU8j{Q4%!7B8{?Y;IHf9r(8y$0B1%FMj&N0I?NO?8ug+&jtKFgnU1fN>P}ou%OMO4 zBJmS(j0kIg&yb<*1i;S=^7rt}4^yYRYKZ8(Kf08#m%i)WTQSz3?UgDEUoOg2Hp#7u zf5QE2p{X8XP;t9=wMg)pZeW+<`ptl?!b+ur0FFZdNVP=1i=$HUm1pC! zS<4cNWObvyKB?&Ptu3U^Icru{b#`G(1(#(bhphEv62EUt#}CNsVa9(d%(Rr4g^u6J zu0rT`I_^nOIeQ42S1xarl?RtQ=YTOe%DzOXwU__nbCdBfa|7l#zcw;rsO0-O$#|ma zscPtw10(-3O!hB6d!U<)9Shb$#M%A?5q~xN$={L)R^SOcS5G3ULkg$iEh{#)r)|vHI897%v8jiJMx!w@w7g zX_^?iZ$WrTLKkysV>H1@bN9*?Vp;wwrC|am%juqfVRf2zCCYM;rq4Xuc%@m1_Dr_{=BN2m=36k^G9d%pgVqxZ6^~4DZ&V;@WD2 zt!FTe$7G7V#p^(k`~cZh5oe!Y(y)X9pJc_;J66~)9NIVEaXGuf;4oq0qy5b$jG=9c zKw2EbEFQ^$ZRI%?8*-DAk}@e>c3)y{F%}g7-QmkpS37)oujneq4R@Y5dpx4Y6r%-K zbHR}okzZs~3?)FXqN3WUr5JW-Y+@8QbgB?ta-`m@_P|R$GG3+Mbm^^>sxJI50+WRJ z!Zrq^Bm6^AGKcZR<7Hl^MZ2FU~aXC1Qc#$udz;TufLG(A^TWv{+3`d<7ZkOW0+@`=}qaFU?k$ zN65qZ%bc*nt1u!^z(ah^kN6d)tx}NK9Ocd$*VBo^#5tQWpl+}Z__+COM3BUpD@55H zWkZE@^FU11ZRf<9Q~@bQ#Pyhrol~G|`v!vpku+(}?%XIQBtWT0YX<@@z#4(VF-mIY z`Z`jDtwh#2l2RcU$V<7NxUJkR;l4EX^l>gh*E~`n&_vHv0Wg z0K3kT-N`0!A@QvN-2g|_s+zb3O>$|$EvoBbS>c>)HmjP3SevC~TDhVEGiveFgx?1d za%Ww8`|D`)I{~W_>@=_`3HY!#HB|DLP(ohL=irrS!~Gz43E}GtVzan|A@(2zRBdVQ z2*Vi)?79SzBi#h=i_1*e*2_o{VO|1l()A{V3}1+>!1*s48r&Zo?hsb%wV|1AFLvgZ zmTQ+5h572mIX$BW*pNN1LUD!vn9KF8T>{LmH*Bq2?cvlQk{UiTOvPq(Vy4RuS}o@a zuV?18sq(G~Sy@A8LbtxcE}zSlyk?V^%&*Afo>`QfI9VPLRIctQFM6XOTHx8|5;!(i zguvJwAs+RuVv?5;GwJK>ERauVV4zJalh@*4+uE z`{meVHdX>(#<79@uFc&V)XE>5$cq@K(`>Rvx@Z5FG=}J_h#4;r8l1+15;WVe=Ik1w zoiutU)f%*LT^k6>T$aGO)6bC3d}q}oAXTZ>)?vJOsaFIS z`{PME$LRYJaJ+RE%Fd3E5L&uaaFGDfgqGsCKB=sbah)ix=I^ama zx)L**q%qHOQYbf!TKIV&iR7yw3E6V{AI8)tn)L4*r-8fLU9$sP%bLzmxS)yP4WuvX zQy-D@^)ob;mP^ z0x}p)Xha;A2qA1&B3J*>twzP+Nd z5~Lj;2efS7A47azusb#&#`Q~|$m2|*4BpYh>Sba28J`!!DBRen z8?x^6^)+kh5QW8Z$(CK0QJ=YDeCc{Jv#aCO%MpNB1f}aC$=LB`S=P1gd?})=%oWo4 z?i7nI@+p#}3rXK7hk!G`$1b)I=D{;SsC zT$HH6WWfP}IfV&Tyvsqf(Ckin-%P4kS81ig@3QXvT)kj6he)gqZM%ybcw0GhFcGS> zPt>WRPJ5i9LaAP;u$0J-Yxhg&?tUqt6w`tPIS|hMvgT2?dfK{C9mB4B3JrCShxXbG zWqiNVu#mfS&Eu4wiO6r6P^hpdx%q3MRozM_v=Bh`Y&Hm&T7jP7@+~)2GHHQ&dVYte zTO~wuhrC9WpF6>PDf2$D>N515uqKAsB3unZhm?d9SX+nwVykH_!mGhTIq6Y2<6+#` ze(tOsZ`u9_Mznw!)L6@1QrAZ&7X62CC_41ZY1Ze@p^~jmt(@sD%uvL1>oV zT_U$D8;98m0X1M%uDafhkdo=*MMk~DF^a=6xmx3zfYFUIF26aQ=ljI>m))!j6Xv5q z-L>9jGYm>;#Ye_}kpMZ$Qn>3*uaWg$eLPr%mtBw1Y>uN2wd#uTQ|MGuqK$L=Ng$k< zd-7|BJ_qG(^JI!WTgS(s6pbuw`ld(%6_4X+&l~F~AsEQYUZEqaqJl~HwB?$-*_QB) z)3%%V9`}}tl{K93>3v<2?_%8|=-&+9Ae)=!WwSdJA&l_cDvLohYTt=+z1**0nu3%& z&y*cMcUaa^zd|m*w87VHH%f9pVEFoVJ)wQzcJco8lHH!TWZASx#s*{F%JI)Z8gPHN z;w*3jqH#Ns!06WvhD;;akoPMk`&xR3o2Oo;xYVXLgs7I}Sm5y6C1xo&+LR zo9&jbcC&$r>)dkS`}J$^MNXuo5BF!gl;(v<;q8=uUrA$Q&_cQP$Ri2YyXD7_0|;zC z(_Dk`faVdE%pWWsiJun`0X)+E{1DJ#@@>9t>iS4S=HIh*d(Gff@BYT6#{|<(l>^qM zqW5_-2D}EAEmr2bdp){iF3Ckp^_Xn;0?qDIRq9=D#Xkr%ekW7wkmIjdzCJYbKBgm3 zGd2l^8bwdN617h}=F}g{dB5>yc+8m5J!SWsElr`Vd55M3hJzf3^$}){G70D$m5M{g z^=@yAUlH^w^>pw(u5v0avRse0-!6GiF2D4i7G-(;u#ZZY0AWc@dJf~{Hj2olx{9n; zo1h7I9~E-NMIxibH!9d+4^I0-Bq%+y>GW zBg*GaW($dE-M_p@!T~ltKaoB?9xn;=K_+npNy#wuEzk@Jk_6Jw`m6VB1HEzJu#b3V z**Qa}7~at?DZV=DR);!{ClW1z3RU0NRa;^>j^{}6(L|0ITRq=mEUVtsr9cQdw$;E% zkQV~WP{1(XB@lojs={X9t~1{Kx=Z_?;?jw269^w1R1hJ2H}gtKw48*e3mt0GX9UO4&cQ2_`z;$ zQryscA_!Kyaiige0h$f}H?TQCHJcL+5++_tp-g)uwK@9tQ6aQYOo#vAWSjH(-excg zk=PKSJ^nV_lE__#^M>VPhkV%W(B>!6V~x=BM6Vb^Gqy}StMerD-K~XJ31l|^-A*|0 z;?_CDdKg@&ij>WHkPB4lUn2=vGe42H&#yoE)-Ei7sqATmvi!{j)3*qW{CNR+ieZjS zmv0{jR;Fp!&uLsDqozwuFu=2A`{VRF#;uu3&P}(1{f{hdJ9?AX_PZPViduUf2>!Cp zXD4P8f_=lonW>zxo2;n4O>Yvt?@FSiyYKdC>+LfY&-(hsMkUSF-Qc-&^Q z%1F7==!w^HwKI!fP2@g)?XXl%YI>U(dAH$iqtFgMy>&BIxxXZo4FdVe zI}Crykj9Pl=K{BcMCOuZ4=4svQRGkN38lQ=e5Ep~*Pq~qGDHtE>`APaK|w3Zk3%fU z!EPB*4l5msK^mSCcVa8Eg`d-GO5e$}DGY9nTqO@$rE7P?ka_HD5T;kgJP@ zEamZ_!{Tz1|I_`V1$5Awr+~_e20SxjF=~e7=6+9iI!S4M>K&Vpa%OLsU&>7WA5=0i ztW}8U_u{fLA-k;3Vc?jJXBNaH3pu?GpOuDGFB0A+#^7b{M<&lX?=O$z<)@odU=Chu ztFg&drPA%e#Nc>V;qEmhk+_&xOW1Z?DX4P67Ii`V6&HNx_v1oYe_d7*^!3tGS|*3# z$)oi)b=SMAhutLklt1!Y#VhK$w=xW=xOmDbA5Xg|PqXVyr5SrptHgw|a)$S*^X88g zo{#+5_Z>MRAgyU_V`JexKf|t;%`?UlMuWAEiJADfT0bX_C7Sc8>PatJSTR|Mh`f}*c_3d?WomH z#PESIxsfLzNvtowf{W|)N<-Q7+}e^G!(tDJvRbgyv*tMD>2g;CBd?|#+=s#|8ET$2 zd)VgZoUp@Uq`#XDfuaN!unPa3KY{V%kr_GfEz701gr=A?X_`p(m9$+4#kdhtY$Ijm zIFfUtl5cjy?a=Y-9(FM{g5~WYu;=brAf|Z9Yh+7BZ6h0Utq}8hhZ>rrl3D07A8{d%(8kCVYEq0Y%_X*NSyJJp$JFfIW~uFi!3T zg3x2jj@-6d4S2>~ceT>>nZQN8aWLQO3xl7VNLVw~cL+@8M#}Pd0du1`WmQ#E3&#F< zK%C@06kc=KB{<=4YJ&s5-CwJM?Z@~>3p%Mry}V1K8!zaRMJ-PanZHcIfkX2&S}Zm4e3NgU}^s!v#q?>u%tTQtoL1R64(#I;LxDYuzTj zeAi>ZAfSu0jP}!X+)bRhVlp!F7EqlARH`x~N--m!?yj?@&!`4#~&_~%Av<+IP(E( zoVI5^dr>raJGr~~a@l3O!YAE5c6GJ2ZD)A-x=-&{T8{{x#TEPeAl0h_!5Td;tlgHe z4oe>)y04!6IYU3MvsHwjpAHoRgKC?H-Rizii*KS4BmPo~GuzHLem(#$n`x0#k5fxV zQbJPq>H0$((v1tPpwXk&Lz`H=pjk~rA5Z99}<DcHMyXE!t-W#5#5uaIMaALvZGY!#996sMPZz%DZ zuw1m)wxuf&f^har5|#IIa?x^%V(z~m$yD_(iL9cOy~pZ3nb)Ftuq?Oa&C}idey_y$ zzdI~sgJ|I&i0xQ0oQGzOR;b18C4sjSMC9}|#LTh!$ch_xpCLl!?WKFAu;Z#1 zr))Hc(Cb^$(87;G0^JwRkZ4O<3H|@Od_Z-y4sm^TZ0zxICjFEq%x~@*|9@4N-&6-` zPf=Qp@nmA#Bi#QKogZ<%Sfa!KeVza9pY!W~@B07c`b>{a#y{r8mfl8ITgu|8Biky^ zJ|Ht{u6By>7!Oit3H2Dekx{X872Aq78bSN^bX3;qc*VCrS0P!NBEO)ZXUY+_Bz*a| zSp12*foPw8et`)wIw zB#zUje0p`uTeog)e3V#`J&9%_d>6uNOvL#Ns%hH%ui7N}34_S6+8lqGm_4nYIJP*&%h+VN%8r;6e~$InvQ0bTTwEY6AptY^stkuo z&*w!$Ri{JaP^$#PWLJ*QQ!&kjFG`QtN4@-%@vAii1IyLK95;N43>&%-)mO#yT-q}y z7)z(LJ0xn^wGdL&E0N8R>LE|R+2eqpFG2B?=uyP@7p*p1AH>U?uq8++JN`X_NuK_9 z2wg<^x=Wn_BKo2~xDsyGk>z89`m~d(;?EaqN*dcp-e0gvvc5lAl55fYzn+pM<6pn% ze$Zk1zt4P-LO+=Q9j^cXd_9gFylV~Hm3nq&c|W^*ozte@v}(8I8~l4b+3p*_Bj4@* zVjX5;LIyTacuDo^*RMMtuS8;?zDgp4c0fgswX7X7l-uA`E(FN=gQ8?$X}`;My)bu|aNTw9tSy>9M7n-RrfwPvu9@ zrexh_AX|hHOyKlYJPIEPrl6&@u(a=RC_1b7g4J|NZ&U)28d4 z=v&bA#Zof!Zb^C(F)eM{Xm0s?&9s3ELG${=)pPsO0wNv<_@~FQKuAEJdaI>fn*k^Z zqSP|(zU_8udw60@L|YrlLEDBOXvwh~uQb`MVUiIYh;Z0*x%tFu%93I`Od_FI)FV>u zHbL`01)Kj}Bjxy{2ugUg7kr!?Terju{5sK@{r)q{D^uuqcSXp+?Uuma9jROJO;sWX6&X60@=*l&Mx6*+y)3os6E& zcWA`4p4HlKn~`#9RH**48@QK@fQNi@h)f{+K|d4~5QvW@H998ATXE=*0>BTBtM1KR z#8lJqX|PzV7jSxFmi$&;TDrE^!B$#K8pQ?O=R_E#rt7XTKR>u+5KT>%+EVQ?FoQe< z9Y<{cY_zC|7t++`#q_P)`|}m~QeUD*|$ zb6YHw_uq5=iW(galNIRG;Spc!9@L9Y=e6!iLUbj#?0BRol=&12r6|gDgQk#8j*w#P zz>VgA5p3h*e?7x6wKNy>(jobH8nUms1i<|McyoO^%6qJCumuc75L5;H)u=PJzFX7j z2xGE*8g@F2B;rJSf4$#4I+S)mF(5UXu*Erw4{AJ2nZP=FDGY4g0eHqHB?Zd~yxQg+ zE?YX$Y+BgfPN><`UvMT`KV)vZ{hq!EX9TPlZy7YKFo8~(=-q2njEtu@?PB2vyZhc9 zu;BxK(|Ln5RavvLyh;U+1>S%vzE(o7Juh^xbSi3%#f!R(2BrUAPy#kFzCXPoZxx6l zVAGpw-}LHGLckyoZVB;H_XH;mN@upiAoE?J?j7t=PX|VxgK~Qs9B~vcHwL&qp5mB8 z07E+TMn>c=ujk%*wWW&m7`(d?_SJeleC^K%7AJ4*?cn(KXn98O%L-pP6xVIT^u@7gUj7Dsx=MDhlrq`Kv?Fes@Hfc^&c1o@`{U_(EqMYOgtTqdG`&+8rXJ!z$kcX{4~@m z;L~1VFj$SL*`+9Eqtj}H#LH`MSB6s#Cj3JN_}tlL0OIjDe2W5{xO{y)4{t^rs@<1T z@wCUaZo9XZPG!?*C>Uetf)@Cz_jvjFrdzalyxAqt&;zF4YzyEcbWVD-Ft=8eYDjLe z_wE7K8E;KXWcCOtJN*mnD=np|{`7*;pF3iHTD_Iai@1r+%8E9K0w~bq>^>-KX+?s* ztO-sRDlYB_Jt{y2CQNVU{&Fk<63_hCE+0b^vNel@!~FXz+&2JuX}zah^s#!)ADl*L z9r%V>S&@XpzS4QxdH1%nT3+jxX9g~Or&bec7M40DuQ#$IGQswTm9bIV&d*MX=_VV2 za_uH)j{O{FSvdZtbti(EnHgrgUWO}Ij2fNVquWItdkiPi*us*MpY&!sF3fGR8w6_F zo@k+5b!*o&AJ|zPM$7vtIHo3*v}7N|A0{4&o7Z0m>h3qr zI)FX`9KXRrRy$3cL>_GSMQ|r&I|`N z#7Ou_MKbJ9>7C0O2hWpt-y;b5qefjQf4Q$05L7mSR*0>g@Ji*4pH-bN=>NN7!7Ue* z;j#RFqT+iwVkPT8EBwfm7P#zu6+)MP=&kbYP|wo~9Y16OnX8Y?=D02s zc4hq?@?%>2DWT-q_Ls@S>6XKEcbbpu=)?Gsh9N?CXRa)RmL)4Ea>SbKdXh4=s@{6D zO_Ht0rcRRv4V7{tubLy<<$^^YgO{sAPLr0|LV2*f2?~$b^+h~>Mto$01xD5cY!r7v zW(*2xMZduzqEGCpg>bpE_dlSqPTAeM+iFAe+0Cu(2b4*-+%sT*k2StKp6o09&Ul?{ z@3Bd`kFN1&K!!766z7HqrisG(FPU7NaDLD$mN({LWMuUB2P>rg;iPa~o0)-zeD2!o zr>6v*bCS*(S?^BZ3@_jt{ zyBueEpWb-UnTqA1y>S`PG{z4|VHIb2zTBPKf^GqV8aj9G{jIZ|9xzel(aCOnCuLz} zUCn3%?LNhN3+Yk37wta>LjUIh{vhw~E5f_!3BD}d2Q+Oyn6%%lNO7G;AI4o>VdCuD z>@0R?epgArWZG$kryCD?C4nJ|V(fauA4_8FK@srCOSG+79DY934)gQ#P^UBAXYc6= z<(`Ch534pA z9=rZ6e`VRT?aCI0QW{L{bpMCAuMUc<`?d^$KnNNL?oNWcLkRA{Ex0=bYdkmvhv4q+ z!QF#HaJP^~8kfeIOY-}^H#L9FRL!ebmFh|--F>^yJ?HGb)?RC$NC9VV^iv??%GC{@ zi#vX$l%dW5W(1(y0e}DW4E5%QJrTUt}5^){yQ(yL_)QqHE|Ns8f!jEv6?hocK>a?k9;2y&%J6}UCCMx{SIVeL5m%6i3F zLs(8X%LnId%?45IBR06c4g{_H(l7`2RwT0(&?&sT#NSGv!Nq2=Ydw+QjyZ>R2(`@c z4gU*yoFqh#cY~@DdrK?tmG4_2v85-c!%Ul_4Z1cBR2K;o%gf=wJyXQ%r8gyX--&75 z8zML!U>oaCcU=jGMdN;>uInc7i7`=2t*5$Yjy)Iwl^B6JhWWZ5Tr_I}pQP;Mg&oFtE8q&N^T>b$~Sqxl_ z+t~EP0o~kPE>*6t`HfR;tgI(}Wqcm6<~A2$Ny8ZF+UpD&TfliI9N89W$dI8o$h%HX z$ZU^3GBwh1v+(cq->CpXkDLL_FQLlEOs&fr_lqGL)96!YAe$`Ux0%=W=ea+x{Z@1~ zJ%wg;n6^+Br^x-8lHlSD6K*>xf z!{`E^`PFd@(C)73Rc|Yq(BoY$hRo&KqdrzRH{McUU*eKo2aZ?R?PgBcxbJx4@hb~! z>t27fm8osD|jot2|aGcxpcn-VpnB?<@KHJvga8`x$_X8g@ZS6?^MDw%L4^IbEDCJ zWv6~oHL8Eux^Q*aQt8kMgOFRKzO-#ZhV>>@;H$=)k|J95Bgd7hbv146+6CzPvtdG` z-2uF*s(j=Hiy|$?0TXVk*>L%B1BbK9als0>lJ-7W``HDsQNzk*XX8m6v&W^v9^oZu z)AN(twlnuefO56duA!w5+rPLzT3Ql0(-t{Qkbca%e7@)TGmmupGOWm^&kz@;J`pKahfQN(A}87dc{c4)<_jb+9ZaWX9qH)yo_)tP zCE;;w!4^<24dq{0Sl~X30>}Pvpt;Pb(JQp@+@494;tnmfX&C1_!oWgLYLl{UyRbdq zUm_72zX=TpQnF^0NuXEad+*S>bvE9iq7!9At^?}Y#^tsr1^S#y45aeiLm1;+sC;Py zYUKT7T!GN(nY9<{+G42iE|TXv*#%{us#<(5X$QK;K^()PA{8|{bWuOgELez*y-IJ ztjTp>ahp%bTPEw6ArtYYRp?c=)^fh^fR#&0n%}zzDl)wQt6Ty%0A2Nwsp~=6aJd2S zV(&r2N-2LE_Q#a{eajinOGy5=fc=C-$@c46pKl2B`H7zbb8-aH{|VwxF#zoP42cnK zxx;%G3&HreiL!#wS>sKrE8nKgWTyAtk^VSN$6DocM4Cj5lUS4hf$>z7`^a%Jbpi$1FCcPE>=UUXx{@)@l7)@n{Vw zI-;~CB0;F{=%H!rNk83{Lh8ZlmW{OKSem9KmwL6}r)DItR0>I9w4KX)U$Fb7B#Y}|T3Wyk+RzM>ws}^cZrxP<=n7(ed>G}@Bk#!i=;knz!lB$}zVWQH_ND#8>COi^5AweKO z2@+N{7SwC$BpOtIX?T&zZ4mo)wD$A%tC2g4=EZtXqbk=|c9=ru>-r|1Oqw-G0Rej7 z8kCp#s}UyYF;edsgtNI^1W+SKmNIJ*hEirqzcqYxbOcwsffjx)*?Hw`LYF<(h;(!l z1+wPP0**52gCFh@XrriCOT7AqMDH>N<6K2dP3tklfdu#Mo@$;83jwo!)vKIQ;VR8C zeeR+&xOWZpCWC&9S;GD^j2f-yVFESOa*J4~!6FP@i_ybOE!YyoZe@$3VSVux>mXUN zHV>oSpH#GT+DD^#6+#Z`#-=8QC!2xgGL76jC%*<;j7D}GhEgrAznUanoQ2PJE-$+@ zj`5gtF%>Jfe5*5b~+ie0w9J}3zWNH+V6#<%0t|-%ih+& z(FZWtkT_J1zQ&==KK$+KOn9RANrla)#57$&A0|sA!k%4VBUhQzKWblhTzr)9t&G5QJ^qeApb_^Nr_6el{-1a;>}CAnVR}T zQ5ToUubRCkOX&f$|6*hn^0!x#K${73SSFsO>6+R@`CV+d)YX_{jP75oAO3k6oWU(Q z(8uxrk#zm{n*o3MzaeS=dtZ3XjpCP?Eqj@oNlOU6cr!l!ua};&WzQXx z5rbGc2ip@O^0Z0=)@V#?@pyQeLM9u@@WX5_!N862HK)dW>*yd_6#Jj+7~;NX$5(`H ztYA)-V>f*{MLGE!4f5yzBn6N~f-CmfIkOyku)~ok0hiW)4b6wIWPsJ>|LgOm8l<;j zGnQiV@{Ffvuk?Yl?&s&f1ogWI^ceiT4n&gBg%8l_Dr!t1i7&tR@=C`~?XB1M(0Lk< zc?=*uEvS0W;&~<2 z97KtQ;dFw}>NB{2Qt6Mu(Vn|&N8XntP3I3G8@X8)DK~t$$odD18~_K^Ia_mk=wa|< zJ^f_N!;bXLD?<2{<5H1Ya8 z-OFizEk+W~))n*c;p~8xj;^bcij7SKQE<}SDfp#e9L-TA;uej;;j&&8aB>EmpEn1i z6h)U=gATOUAecC`(!A_@IQ8M*aUuuCsRtm7hv+J(9E`~e9=Wmfyswi_m3VdortBF) zS%_WPu<6qZ$E++Zdx457G6nHKqXVY>G7HVd@6^LQn6=Rfb5a8(Cdb?TskJ*zZ=08y z<3}AAmmMtoiJ2ciehi6|=SRWOaeC2y^Bai+v)|a%^d}_AAC8P@bkvrLld3xQeZ261 z+xl+7_nK7J4&AF;Hp-e`v~$~(Kqb8E*TA1pVQ4pU@#U|<^Tr4TNgseB(~p%%lU zhFX-ZeIQZKTfWwu&S8XwMjs1N7lnP8`e}&>;5{7vKALz+K_gzrt`!dabk*79i>CQJ z8*KBdf~DU( z^y4YIXi#Q9OcPJj%X-<Uu%CB{N!w;jsLuHE60A1Yufq11o@stx;>;{uQ0PCpYf z>!Uw_`gs~3nzii@oD=JQv+*#7PBamx{IUp}+Es#bI^owwYZ&9gjn*UlPob~ja_RxYPsw+2aC(`IUIk4B}Ni=Se;%KHqT@j+X!I)nX?{A z^I}43I8;;;fOy=uH`B4!iJiFD{w+v#-ebs{G9gX!=pfIus6g(P*vIEYlVfLSY^Wbg z{Zo`;t~ed^Brptn{RuoZIg8D*Nnt)rI~|!zwB(oiTk8y`bhGNTP(GQ6V+bYLvZbM9V;vAM@`jGuvD4> zn)YQ$+s4h(be=qZsAOB%P06^9`>yKM!>!%)yzfT7JS6*kL*i%yI0NS}x)OIKSRhtr zSXu=ix?<)N&xmaff;b!t2Nw?(1N1WokiGh37Tq!Pp%DckF*XwV!=nNR4soq{1t#h} z@Wn?U0v#-}c^@ATj?}=!UehN-`@u9V02zCH=wY|9Z}$*fZZh=EtN2c>;cRumr^A05 zfO;#;=RCJEj~-dby!d2sp|m3>J<58@y6*3CAN9)xJ4%Vt%U^=>B^6(H%x6kv^wu zvU=X^=zbbJCV2Z?cGZNd6?&)*+8Ui>wgzti6b|ML%jGXAg>e;FcH;0=w}CeHuq0pT z<81;U$zLos+pOw|?4H&CiDC82C;8s71*#4J@}XJ=!qg(YH5m3|tWjkkHtk%~YjERe zCTo@txACCrW6Sk=0@Z->i&mjD7i@Wf?I=slv&Xhmv^Ut7-F0)z0lIDOJ=QE!u3psC z^7Aj03%!B?tt{>9U)@NIJ>X0)**Mu@Nl{)x0KG*u&%O>O$!+f_wR(5LDVKGub9I|e zlcj;YdGrv9Nz-$5w$<_Ir5#F)g|(ejGuK`|JOEvTlKuj3+d1(7GYds=D^^*aM`U|{ z08favE0iXmvA_Y*1GVic%4|j>^o;X!FYQIsl5JZsT$*2REC@qAk{e8SvhOr%^Cpe;awsR{s9Ud*eCS&r@i@31r$5aB~lqhuwEf}2m z^c1UILh6=A*Sqk>HD+e!>OJ(DbQ<9F>KCl{%-~TVAR9ikPyLa2Q2?xX$COaMav{FF9F6TL5~pSk z+X{Y*QMP(gy-rvR&jkeS*Gab#**&jbs;H`#IJV#Iv9(?v`50{e>>Jtw-&P6^_^g6n+?#j* zZt7^yP_-2xPudl&) z(x347Tv}72@kE5wD|G{BO4VFam@){PFH=&xa34JK(<#1vd~zn5|2A#y%PG&i^Ij8hQutNDp> z$9$o^&GYM$-N?$GJKeJE^{e2;w()L4rU5%X@y$^#LR6Xvqq3URB4B)~MxXQ&U9gzg z_MpV_7dFqCT*TeA@W%xAJumpiZQCx75>N0#*`z@4jV$>}V6@DpIs1k5yoLMFHhl+* z0XG1f;eh_&rdX0xtuG{qKh$&|&>?ut~&~kKSTRA(L*K)#W*2t1Bpc~Xr!5bMGQM28b8ezx~h)IBX`ii9I#u^_t zjw~Wy)DGtjCb1i^Vl$*f?WOF^I)b`s)8XDkX1lJnMHNB0FNv8Rhem!_VtHP9BqPG# zy}OkA+@KIy*h3yGCs#E;Z3e2L=9!FLrZhZWCo6}Rk+V=Q{%*Mh;;|Be0;B~BL&@Fu zak)?<0;XB(=V+V`nt&6UPN7oYP1CQv`&elT2|^)|XLFj_o39LP$l1PvX*Dh@w*s-+J86rD;}$2Bh&8a9MnByt zCmin8vG!ZSFTiPB5^l(L+`HXt_q=l9Rf)rA<3h!&wF^Yj(fS(&SygkUYhjgrYuSX~ zlG-$`JnE}RPp*I0uWb`p|LBYpmPugj1{4JbWRoFA$W%06n*9dg`58CnqSy+HulQgs zPD8lLxOX~xj=KBEcS`j3e`rb2da-qyF&x!4e(S1r?QV8y!yG7}y$~ z?1vj)M(GVt;IUe#OI;Q1fC^syO8*<}SBZ*%VEi<^#QOCVE+d^+j{{=F8Mlr0em=uf zR%R0u*u8@6qL3lv!+1Gw^!2mBZ{g>a10CnFrQc{qfy1~SrpARz@ak&EdC@!+7Ss_1 ze7Fyya0T26hv=l^=O?ismdmB;F&MU}R)~8)YzJClvC*x zLgPU~OLZ)KM5fO}=%PjUg48pMj1{A!?A%Chwb7D;jz?k8FQ)PDjy#Wb^qMsY<5IHQC{`>C-0(1J z(#7)9Z2aL5Lr}%=8ZFZnejHxlve&+;12@p0c&<2?`08&WBk#sKY(f2l%u#Tu- ze`LIGb?h7ETFGDC62?V%;rTn6W*Svb$6>W8u?Qz~oK23+CneIZ{a*T@Q&GNFA@P&v zi!lKxImkjSQY;@dTn8RW&iCVbIB4>TLC>3{*TiLNy_!Rv1J|9j-VP{A5Jh>>`gk(7 zaCBUZ`Bc@FY1I+ZsR53AiS+jt51EUay+_beoT)JQaC$@F1VUTq5z?nsyu&$>$YQtL z8TW2$Ku#qNzg4to1+f>&=aH_W{f4^kjK-tk_%q`wgC$^jz~u)OMkYqMe$K_#y&G_p z-f4pTw9;yj^Z}>Osp5kqn7(WC*JZpw`d#GklBwtBE-Z>m(#!*dxOmSnJbpzC$-nz4 zlv#K(!a8L4?DoJFJ%ijJxXshwiQbJN!)cQRlgVML`VCWZNm)rJpuJy;4HR9x@?53* zZnyTp9&}BCC~8(TScb<|@Xo>7Dp_Vue|!tD1E30dJ`xQL$(YL~&bz1k^FsI6^lZMc zxUMoCw0`-U(Pcexh|+xMoZVkwV5i4xPWR+8tX#QO-U|~4Sif4;@$CK_~RNtCm%T8?;&Rx?A3K4lOW*#I+%~M z8gkQbh|@|XQHRCMc)QgolE!)YfCuOczTTdTv16-d%D7`VxGyM&n8D)dvI!X%rqA5B zdRJ=s)$wfC@Em)A8kkXEF3ito`6<`f&xD;0EY;WW0lhqyRC%6Oc6a2L4w0VhkNbJO zL5(}y1NpmqpiTVUJ-&nnLnvsu+~Gm83Yo{>0ef13CKLLibav_Qj4Dr0WycDXazf z&9`6}kTfBiI?BrVeiAjV3MzgaNWe&Suq=Hz-nD=Tm5JlAagkG^Da_i?<>JF-CB%Yi(T%c*05^mxBGAJjeAj+UDwhn56gVT z=UVnk2&TvH?w&8ZFI_yx<}l248Y`P|Sup{%m9H-NCI zo;M*iHMqU+-X5B1Ct_p6;Er_>v~t)<)bNN`*?!478$(a7ylM_`wK5IGYQNrYU4 zxp~n5%G^ppZ>A)r-`RKz+;9S87n*WM;6IZQn3cu;^t*fgjVp(!N88(20M9scFgEF| z!|?c-N5>q{F*$fAmF!73ev$|Hqqo)Iu8w8@*A(IgD~lYow2(jnmrOqyMm~anr#BF^ zvB|H_na?%epa$n&*u^ct#SNB;lJqdIS2gg69}S%25``6aSXq|Llr}2p-EDklJ88hl z=mrdU_VWf3x$W(!Ph}=Je_vE6|9RQqk0H6gs%av(+u|c_8f`e?EsiVEl6u53y`kTu z#vju9r-~(q8irLWTHe?t7B8!_b~rx(G^~M&y1G#znTYn|;Zz}RjHCvlpl&6CKLU#H z44_>OAj5V9{3jb1Agyt*kpz)5|B&?D22iv;9_m=_PPOX@g1zK}17copc=8nQa&5tP zya*2Oyyt3R$wT52?~GV2fOcIXCEzL3I#P@XviKPO0{A=GQ}uS+yn51Oj~zW9G`BbP z#9@6o@K@CumX|gVRbtfOn6KOrmy|nXa;y!P!OIUN_;badT#M5hR1Ou`@gJ)X?zO=R zaGAvY>T909uxPw+G?`ZjWuMxfo84_#w?fw%rmK%S9^oYjz3Jt-H{O(KR3jIreTFYk zc+_P$lm7f9wuK})G;RU?{es6=KM+zB6*s+BE3KRI2)cW{Q$77L-ub2`tYGIEeQ4;k zF(w{W^&74nlvH6uvp2=zzgRfd&0@{Kpse(vUddLO3-7|xqi7Y@tP#_&uZY}EJItcF zig%~O3Qsb`^JR8*{L4iv5-d7q+*gJG0bHK?UN(&zkMD>d`Ka}bItY!xccVw51gZ)5 zmO(rC`V3s>PFhGln7pDQdP?mik*9Mht8|~dkJ^OURfvF&8oYkyHgm)u?S9e+J`SE5 z>wZ0JRHeV+>3PyuxQA=k@$gF-ZEM+)k#Yl!JCZ6yVApnkG`pWPY6@5)H?HO$??n*# zM|^}p2`fKBlYJ|tr?LuF-SjmcEcYJH_~$Fujt$b!|9M~^&S1|7R5~A-wiNvjjdMk8G{}dRy`|$)U)9?vAZx(`o3=jACLxseTBKm;Ix0LQW zpDkes&hD}Ao59JcFVKpRs%ZOd$`R@`NoAH(RtBe*D#yTQmcXbTF0|rRdUM|h6uN~G zh^YT=VAf{9V#u!Io{E28TWyrSankr#OL#nIMxri+gcLT7VP8mBK1HPiR1vVJGCJyZi)?$hX1v>nfFgftMdBS$7eoZ z6vYpV6Dkmv$oRoItY|9XJRBKF5|yL%LV8g7q#20Jq-ExuxqXmBCB}uIO!L-ifTLh* za^Nud?^xpeV}uNFN%Psj!{u`!XY7Dj5_*h;g1{?tOGMy&Ex;PH=Nj2GxcRZNTX)`h zPT+VuG1IwmHAf8TxKqTHf{uf{OEKz|ORL>HJoD+Y#$!t9I8nYHN)6J7Ib9i)#lgAL%Z}|V?%y>S+ z&Mg3FTuuO7XxKNjog{EeL$A|}+t=sCm&RvzXbnuYhpTmeS4D00u#S!^bwcm?$s~3Q z*1bI|zBH1l+;_U99jo48A?{!6Jpe*yQme4+Fz8KSlsSr|d_lLmO|Ob*gHFS$st*f% zqyB@~%yJbhRHddvB_2E3q1n_0I06AjvV{boN72*VzAB#_M2D>TJOeZvBoEMSust^f zSICw;<911zXzc!Y3(5j$K9{|qu$E!YmzO*{ogybgR*x!di3G8!alwFx4H2~k7O3LV z4Gj%VALjho!>xt>4_qN zB=TQ6d84_hj8nF`eA_>?dogaD@7XaWwx*@M7@+4rYU)oM=Dds8-SX)K*yP>6jwA~p zsfA%ZRot~Jea0NT_%3RropEzZC}p|Cb2UiOOyyYuCUp$NdKIk_y*^yqTgt8Kt(^~jfEbDqy1CR(d5 ziT`K#J~VtmID63J!M&VHYLA4>#^u0Uu(7y*&0K>v!H%Z72wc!3r#H#mR(CcP1+8<2>FuZs_ zxWRiT-?N1$=#Wz%)erz_q8yTgj&}7?TiYLrsg=+r7*o&dp63;k`$h>}W$=ulu$vejuxVm0*%bdHV61* z_PjFE0E(o0vkxgIF3ulFtuNXu2+S?ZBy_xp{w|w#fEVn+FIepybQm;0XJcl|OeX8*EssHPbu3Gr84yyRD|8vYs9M7+z4&?*hh(zB=vniXwmW zN|*~7!@!CEY$P{Hzzn;l=Cl2+jSqEKK?5(R%_0=E9iM1E^4iiB1v?B?2x1Nh2Ctcu zM?(5?q?g?;n`pk-e;@yL&tj3N<1m+Lt7sI1slbip-J$13)Uq-PI=n8da#}F_bK9!! zqj3cV!cB&8;_QujfRG#sR0s4o1Ee(CO!Ij;t--GWs8fgGk;K$~_vZcIk4;EACAlu53kD5W1&D<+-v)#%p#AwvtWZ#shS^ zcn>E(&l-Q#INGnEB$n>$dR@rvUCpg|X19j-P`;@q?KPaha;mffj%ZK#!+ZS&V)aa$ z8&f^{3TegcOD=Lncl#9XHLr*StcwyvF9I!DDlwlgllB7JAY*}f}8t}6im{AcIj z+$^Gq@*j>50{kUdf2Q`iX9A;UIN%)0%BhjPA2kX(4-2%F^ z*q?~0ulMiU_4FlXay$$u{=dAqxS;%9hT{Nn;Tz-K_k1eOq`deP5lrHa0f?{ABDpus!-+Xi*B+1M zf;~AACUS31ak>Jv>f&~PH24X>zTTaGi(|vD((tNqVB3glNvWhcX!}fOmcE@KRJMwzMqnQbymtSRUXHd zkTb458wGec4hu(;4mx=G`ATa{z39h5%7bivIGu z_rtkRT7*4q0MLv?!7E6oSt1-a-*ov7M(EEzxYHDlCx8vkbVYos&v~BiBBW1pXBjW_4mqt~FdA>0Ng~5QG&;Oncru+;185DI zg!4Hc3f@3Ngf7cYPd7S;pCBUd&+Qq144(Q&aOTWVzuUkC}8M@)KZs9&~gYD1$)KW_8}Vzv`hu z`!bV(zetL(eCO4B%u?t{kAg~>u~)4}8CBeML=_a(XDN042j~Y*scp?gCnOXkXx`qZ zGZni`Iv_+4HS@Mp*%SO~glW}Q!zkxt4qFgPiG~Yw>&zOhS431FWcw1)*HDntY z{F-ySqGj-ty$(o@Nk`-5H=}X>4ebB1)4wq>$uI99 zafL`xt|l>C%>wy_i5WPj#4_b3{YBaag?MLP^5ilkXlesu|FGUAa=Z>3MFDs!+T5`= z9uOY?3

T6A&oh-(W)r+`u}rLbnDpdsv`rJs$}jopN4Ii%sJvb<@n3JwW-Nu9$zzM`B8tM}gHch`P~BY6=S2Cz`JY@NEKG(ogQ!ZbW01MYKIgOoAd{<1Ik((~rllmdxkMX;`h% za>gD3Uueqa&T3jK#Up0X9Hi1~xVvys%ff9J^jhLw_W>($RH6056O$ldSNwG_Z*myU z`lBBvi;ex>`60PqPhtr7`;GOPJh4*^#)DQ2@RNL;lqq=__f~G zh*ooD{R?J#@BP2OT=hDVtAl?$?uqQG9T)NqV{Ci_^z8;jHe0QZj6rKheM49>f4L_6 z9WsgafGveC<#GP6fbrbfeXPbrrfT5OqnKM@hC>y!!vxi@6oB>v9eF0^Kdx=uedG?| zVCOWD21waJ@M9p%J%YhSO8mjt)<&fP?#_w%+t?_1W@HBEvjT#*sa!!QBSa>~hvrW| zkk{_*a%S&V%8k+zvrigWeooqs=1-Of>dda12w%ihcn~Z1&lK`O9W97Z8UVF<)-ILv zdxJQ~Hk>xs{ZV@Wk7p-?{M*~?kCJYe$BcL_2lX_U3uZo8Ni5TYkn}$*x`PQ-@c82= zP?w1%pEIT$>j6-S237~KNHtr|bbYq4_|H2rucmaMKndUC$B!Sq4g(n>QG(ti4_`WZ zoEK`%q67*$4O|Tqb*KTxJEKB#kp+gI`)~ukxPMo{*VE~R2Y#OQ>Sl2&SGgD@rg`5j z&uLYuQD|eO8rf-tgwN{W2YncTqIPCVan3c68&+><&iDDA0k+{TB&LVDZH?D^dzM-{ zm4F;9POCpYQ9bKZG2nK>`~-T)*Qjwqyb~0vXx|g(zc|mu;8y&z2>Xs>a=#(iueIM# zhb42~2c!BaI6GrKoc?Izz6Lb8zzzJsWk`8>hhx`zox*!)Yn!uQ79h_y1%Y{k3~xW8 zI6#L++|YtI&VQ>>DAV_!@brZAehdxue}VC5c3yP78sD#6M=MMZwW@5w<680LD8r`f z1}c|LgSY}NsdD%C{i&6kJ!orUl=xjQz&a%fUJM%CXcXr5;4_e-n(nJVIjeUE0Nl1x zy$*pMPYy?3uASST$*?2H2sN43Wgi{h-TRc>+ylJ?RQ`*knd(_DR{}bR9?vd4D(=Go z+nd+&=QADV)KSZGK1=XF!XlOyB^Y4BytnX6+}`E1UYz=3bfi9S$gUVY}mCZ4EOC{qH?*1V{j`oK%7T z1P73yXGqF8ZbURZL;xKPN}+DMv-fCsh(OCMf1tF0&7d1HQ#xnoI^>5|nVrdZlsLQa zBbcNK2hgUV0shItF`PeB?5dm=S1p7LwstaZL(Hf33!AFf&B!+qqT<~d(}L=njFJ|o zx;t4_pI(3i{5Gcj3QD8ng`+ZaQ+*7UhR^~xz!&7D>v=zllTM5j=y$bOIu> z*u3HaxHr4fa{+$K=ZKe!fqjA_d{I-j0Kvi~XC`9Ji2GBu`EliyJvVV-Yc}@*uY+9jLRxiT6W+)Cc9-y2N(1xXqb~uosy* zS%PjZta~R!1dMlh5U)SH3^v+J4o&{_4TrCpPn-OieY?}a+#H&ZcaO&$XA62LAD6o> zh7Ucg6&<1Z>Aag6kuz~aa@C=ETLxd+)HZl2cd|*7(zKf|z^o!1yQN=N=cl+|Q$voewoK%Rtg!j_3M}kYD6|B(zWS69Oj4$^rikM2l zU#QuQ(nQYo4Ooe-j{~hkdS!n|&l$`bPMk9b93ps-e^cixzS*Q5iFoTjZ2Ys6j1}_x zqDP&^s@hXd7z*!NR!6i-~NcSHC4kWnIR z3Cgf-k=~~;_$5_j4_f&z5e0TM!xwY6vV&AbcsC zY}9Sjq&XxR+YX|5DqZd=8{CPt{LeXkM$%O*Me}}Sdq>Ea++|6_Si!@;M1K5uuUzZ< zogHOV&S6KGi(gLdd`Q7xcpK+)@fWYaG^W#9lFh#>s{^S!Zwr?f58fR)9*g%Uo8yKJ zD)|INm>>T`J{#<{7waUS3|!_|Nb13a<}`Dhuv`!cfhLP1wQRFbDlWfN7bRhBcX87a z5fTLvFWyB)vuUrNcYsLXOE-VxUh04^%eof!CV3RL6Gs+;RI`-fQxQlnvP1BQJMcKI zP&d6XQ!M$X`HLcue~2|xylla?PJC=!luQxp3ONlpxkZNi`PPPo#!napg~Qv@h!<}{ z5Y$v2ll2QX4y_br1zVRS040}>kULO89MU>9hc}mI@opK z1y$4@<(=ZB8Q%z{Xy`vxo;!K{arodKsoL(*9r-Gnm!lE2d$4w5FWMGK=GstRB3QTx zF6D(+XN1ewj_c-e`zjop@BaYhP39jIRKNvKB*#IELeAUB)NyoEWotO~Y)4>}!~TJ$T5K+pUXIdN2xOYi~x zm3_3y<@&sm0y(xv0%Jr;{kXVS%OVm-?#0`X7gF?t!Wm(!k%bfm+C}^*WuIOPSGDtQ z7-U<}hF(w`_)=D*hth6jl|adiUd`_!%26U$qhp-MalZ~H{hj-n3uF5rJMlMZR~=vr z)mAaHg*}wU5Y7?)=0;dFJebcWIq#q>AW>p4JR&@qXXdj9+={A{w$be4G9o|iY!2O>2Ez}Nz4J*GtQI!Q)wGk;;UpIEV zi^-^uamaz;&0KP-=^)#nRzwJOq{x6T`-ESZsk<%K@1>sjQS$|G!g+o}obj<&kKBby zhV6`+DsRqyB@WsxdWqF86Furx56^L9F031c8~c(nDNN0Wg1Z^dz(-K8By9vXFOmLd&MAFjoYh% ze6Ri~eJh1P(g@SM_cXb8vU-jIZA{l=``!1I6TiFX{I?JpV=l^(S1TbK#f8LA&4tK; za<{sU8?1N~zD(`>Yd{U*0lH0pbZQJ14_XoQIEr!{Z$eK_UU0H~BlN(H1!zK%QF=wV zcYB5O6M=>{PvoId6b}qdhJDGR+B~UIeohS`K*?3zESz)~T%2hB_^~+68Y!CfQ#3s6 zW4P(OML);zp<+KKQ?)tWVvzc~hccyj(1Z|t+=yih`eNKX+(z%Zxqs5#J#l3@Y3a%N$j^-e?)FJM5L)(-8RzYbbI3Ww4ftX)Mt?~0`c5o_s6x?E7L72+t1&20? zo}$vwPUWe9f_DT?oCVqeN$_!Eb+DJFA9bZYIWA3id)dCA+`pIOXq(?*%btxvrC2Yx z!+XgEs-8dim}w@W!p6CI(FqRT6=eMG-v3>wy*-^~=@}E7@`-Q}M5Rrs?e;l7>nHeK z@pjSMpwPV~ct?JNbBz>YOF$QAx;d9&&LOJH;QGy?K3ctGQzCGl~-S z?w8ogtIQIDZQ*!I{0~L-ZLF9l&5G42VvFJrlx3W$82crOiPWbbD$64(V&CL)x)IN0 z9~R%Ll10WH)XU7vjI2$!^VdJ80@;nl&S<>c4jYb!prE){kh^n25=2{0#C}Reqr`RA zc-7-_NfPSTj`@9Qd2L!+x6NbYSZVCG!;qm#$yg(?P#<1|nG3eRmPUd{t|uFvP6Ki7 zA|m%7cIb)B?D6ux4bo>P;zYQuS}>U1EEAzhfVcYO-r*GvAcMd8ty0J^V-voZnAgOF z23l>tQRn!b-v-sScOd*euQUurGIQZmx!aY+iLi19L-Zw>WXLHC4h;6BiW7{WSXs zLI*fh5+tU}TzkQ)Wa{t{KYXW%MRaoU@RCg%>5a{Qf=lt!?776aEav-Fvb2;9O?{9; zEG;zD@dv)NQ##F)m*vI4bi#a*dnsWf*>F9`ZAd{?;TK)Oz~Qexetv+ZI&8j|T2A{z z8kd1($k{Ot(XEN_-CSXB#&3Oi%hDYC{H2%}6LlHHn>W1%TvXv%8q1L!RK}z;@jceA z-5JTD@0Hm+ohgx{L1y@~NXdBYB2lEF*oYKwS8GH*vU*FiVk13{!YCP0j$HMivQGzV zhnLsqND{J`Skt_`?miA+GhmCG|KL3TkwDbNmY3Xs=x~p>E-fH1DE4&Kxc7QPvNl(p zgeH_sr9qf8a-;+mGbb_IcINUXRfb<2T3IAb&-K-o^c^lxwv*ZBsmGI1)>`~hu+Mxa zcW^qkIrqDhQ;!}$m?kA~Q40f}{9sAd;D~+xe^K^UQFTP?x@|}Z5`2;%!QI_GxVyW% zyF+kyf=h6R;10pv-QC@t+#*?P?{nI{FZX5UZMK#w=BU5M=wJWJZ0YkyrlllEhp*#I z_5>^izn2~RNB0LBvEm(nhU?F&s*ZKxpSw;Gv2lzc*7=!F|BX+9N=?!=3^}6Q;d+S- z`Lvhz*$R|D?C`RR-Y>#}2&H=98k|*BrSxOS=rhFfj-p9<4PlD}qlL!4*;S*7Jr;B3 z{cZ?`gZ0jj>4B$CX5XIS*|j3LL*jiU$iWiJb4Et}bs019C9;HSo=yLXI-!tSIwB`) z{6J)y97Yk5Q$FpDHfp{3!pxdzL`lz|bq5VRm|J9<DF=-;>;v)k;(cH8usaPn@z)n?J3|5zslDty%+*T9J$XxCdsJbDgP^{{UK%Hfby zpI`BBVA=R6vtb*9tLN9#;kO6X*#@DKF13wfh>IECDX)zX7txBGvJ}h;EIvS3>KCp= z&beDNR`LV-pv;9rB8gE5i!LkSrk=&zXKdy|rPc5O_yy$R$!IP4rO&Y4-B!fzkNF z8BN!BQ;AB`fSZyJx?DV3Ko#aO5juc-8jM3C`>4ktautiGtdEQdo@F}_4TAF#Pfzb3 znmBQXLD>F)=Ry(Yr6GZqVsDYu^9D~o{*CFFzSXeIxwvy^m#OeiM^{tWE1g_l(8) zcc2O7L?Wc0?O~Aq^cZu;Y4+Kdl8-M>s%#3bdviJ0_aBUiSPxba2bBd~PRJb&D;8b7 zCa#uc)QVyUTtjV_DX8!!AuvRr@h(=3hVn$;`DrzQ%(n8enl)7Zv*+OdSr2fxU~rAD z@^G9mepc3Y`~W9lnFIulGF%R6`Ui)JWjjM=N|cMQ^eWNFiw9%Uf8-_D^en+PK_aX| zYkS=UfZXqsX3T(WInR`N0w_wu^ng$(w?1R7*_keqYgYgWis}RASK_RFMT<}u)^E3T zt8f=-@|^+^eQP|9hiY9kf9&%vV^XqKF{POO4LK4y~8LoPmTT7?rdp zegNO8o|whS6)vKZ7X={IR8g+X?Rnvx5ej>v=+nxt$3tnaGZ7DE6qwBBvPEO&_>)?|Zwv?u-4n zxP^ZF%E9ApXsg>%j`TC)`@UGx6CY4~`5okV>1LRXOEJEP5U^#c(mW_b*FIULDdup^ z^l`>Hgkj2OxD*!rWjab;`^Z}Cx|UMv@`eqq!N{U5(Xg`%l4?Z5k7NJaL8#l#%6y8^ z7ZVKZCuX4pH{u5usbtc@-gXNDyBdg1Y&+1%B_Us{Hxc0~D_T6*o?6 zw{7Ba`ygz_rrLaT`9}gH%5|K5eYTF4xzi{E2Tt&pTjR%r1*hwQ`eLdKM|vwxuT*+c zJtVBtL9tqg!sV2}Ts+Ir7$iwk8gCd(1$FLUD zC2qJh7O!Pi?}6JNVh*WIOYjcOEwwdRx9_f_$I~_3R1fNYl5rrsK;{#G=(4IPMc%vU zEu`14#EN|9XMZRW2?v~U+ns?)uxG^WFpIpM5~O-L*rVAk{w;7`U!IC?K82|II-RV_ zD+YZhk*7+mVNLrrPer)iw^2f7`Ngd+f7z8@pjB^RWinQDnSOiQ{2g1na28-nTk*b1;?F8duMZ(u7BxLQgth|$%j|I-^7fh{nM%xBN) z7oGqMp3-8#63zRYmsLH1qVTgE`-tU-1Y!kDqG%$BtD?r;fW+e-`DqUSqfv{~wj~N{ z-~wt%>4~h|ur`^m>a7}mNt$0?G{y*Ko{Q7T;N27w>7it>&gNM&dJ*Let=eHKK9f96 zGF;tu7KOF-&N*y?(|#9&5+r3WuH9CfRMUOe5%{p>Vt4`9VpLD^-<_jeR?5-s-Q5yH zWx!F!?u5;bImYuR9%KRJBtHQzVK{$2UP`Sds306CM!@;*&-(#Vf4Y#)Wj(8zL*r~} zjJx|wqGk}_yMVXfeSV+15~v@^239gx3aBfKx*j+S$3_MeGq^o8v7w%xu@c46h0=OY zRtR6kYLKwC^>$Mtf=8I@C4@L_+cHvmNsy1I9cva4t~f6t-z~pHhi=HrHKAyGzXY(KjQ|Q2MP;q1cFt??v`9ukk_qg+tBr3= zwh)GMIlPH9-e8Q4UmP;Z$|c=d+ogs}7sumxUFW|)L{Z#%!o$BjVpRMrG97Z(`AbFU zUcJ>J5cWPQ(dztucT-*3;ug2Jhy`z8yjMsi;|}^Sk?`{eM9PGUS@9oH2}X7Esw8=* z1cDF%ndF*c2E*n&1^BR#JRZ2{Rz z>7tqAt~5{aoy)J@@+BCQQT_*rqy3L>hhY1SjCH{r;d4t~HUoY=v9Y!3UZebbZY`G$E0b0Gl~BXVe}9c{2QGZYxY*oW(ST=HFKXqk6T`Y~(W+}qmm}&oP{HzJzRTlc zr@+j7re&EE0pix64xh|Xo->fg!_1ya zt(#)AzEf)J%2&_Kv6Ap0z)53R-+2K%ZGTyVC`-X+UEbBEVFb za9&Jzu|5`V**@DA{48#I@9la&W@2KpZzCNykn2P&`jHjnQQXxG2FN>2$lCs3*AFzr zEGEbQ{UsEyTrt8G!CKd+AHGN_ui>?T@fmYS{gaSAC;SC!fze)r8uhgGPF7{uXkO&G z5lCXc5u!iq>L9jyr4%wav@%g4v2AEumBV`TZ}8!*yWBPc61M>0LTPjC!yQ*BBz6m= zFs5zIV$Tu4F&x-PukKL%sH6YGWie#cJrbPf!tH9RS3H*oB!%u?q-6*t8&{sKuB2d7q2vTZ8~UDJi9Zkr1(O7Vf|8fWM#n4eqSsj@hqXZ3YXl|}1kKBptHc}7i8y*i+r!OknAKt%(_WZl>h@dLb9C{Q{ zHy4kndt!-TY=Lc>zu)P9681k7KSze^F5UAKQ{Ebx$k#j0Y!c7Nvmd%OOR2-7^@rdbh+ zyo}8ElJX`nsUR3YuHBcH=&VuxCDI>AUU~pA$WE*Jt>CVxUYcs}(_bZpz`y8R$+^n% zm_^WgW3+M%&S@;ILG|tB>wv_#ZJaR|zewwE%I`#4g1C&xTd4W2wgHSPpD3db>-&E% zN+*h}l2T|4fpEul8+4u_QNvYvDxL1Lz_Q1bX8P&AqN1V?(6n3e=m}h@i*bJGpWf|Y z!2j40V1MMz&~nspZw1$Nh6r(bPE|C#%Ie+dHn!_8(P zv%vZlbui`qP00xbpn2Z|x^M)q_KL0tfa>b;4Are&q_f?m1^|CEmI}CyIO zUVe8BpebQ?MJX)EI~0mn`4+=2Eq?X9Zv)EPk@e0ifM@3Zfqw`)qV01|JN%zO^f;NV zA+Zx?(kP%Mm*&2qEpL1zP6P0$K_<`9Wo?_WOlxyTd25agtiPb+62&1J%>M`ISk%<* z67>HbD*({(f5!?S{@~!}0#+0#I;B&UgcO$V#BIq;fgeLEhd!Wh_IoVXh(7NaRtXd~ z6MOl0C50&{>#ca(SlN()dZl*iwEGYDxQaDi=xJnrtp z-^6~3>W$P|oH%D~cPQCZ>K#~)+m-Y7W1jmA6c<2ONYP!H5(RbZHaXyXSAMHC_}?`% zt2uUe(q{b>#p7P`b7wE$x4;IRsm^PTI1Ome!rx zNcbr|6o|!$VO1|3v%WUSUjS+^eSm_}S^v&^_yUx-hWY1clxkGMc3Si2CqNi4{}W8s z@mP?CqZ{?kBcbH7fu(){bOz?%Dq*8O^4`D1N_lSY7_-tEd>6e*?8DUQdQmPQ;E)H% zhAxQb4H1mT>&fY}VQ9!Dn~4k4evzPG&~H-!-FN>KzyiNf*@xp_esuoy@)pLsxaFwO zpUl-niV!-#NA~7r#mwJ=cx%J}h6Q8VRH|$GtfERVttd$5W-Q=g3fTOx0w^k)5b@Zx z?=5WvHG|FQz(?dD-|pZqF1nZm`^zk5OwNf?brRRfpV9Ez2j}b< z(G(SBLCW8Yn@EMuj=vc_T5oMITH{PtZa37M-kd0|pRaXlrBEOJ%KF%Z zq5@WdvZ=!};Kh@r<@J#wSbzYqtBA|0%K8Ac0^xwiu4C^ayR_wVXQVKLiIHsY`@gql zWx-n+W{|u~Gn7jrEgU*5JUU>+-}vFh=k|n*Mz{+LHGk_Uv+Mq`04;?JVtJJn5JW}; z^%vY#Ol3-`KJdHY7aeGVzhjt)GpfuN zlCKBVQ_C{1v{dRPj@=yDopwgm^O*`RxLp^$O!|7xPy`4I@~vhcEc8p; zKfpAWoFPUWvSw_axQJISotRAyoZV${#H8kB6*+C~oyXoY7C_V&7|)qz^1;140^F=m zn`A=4j)6IAGs%t5o8L)^eGsg-*VQXZmxYtNMLdH2g<4~_YR z-0-~?s0paf9~WULD9un%Q)nH2LO)5@>5b7bdoVLd@b%rA&oxKY>x@-0ZyWc>s!ckQ z^yod!I_r7TUH5#Uy zl?t5CK=RxU02?=R<6eQCs73^!4XWbkKWXQPIn@&bhsvc&n$d5@M&(rA7GSw&M%*`BtID@o5}>9nb7-w@cK$4zf@ET{WIfmdP~}) zLAmYYM>gi`&kdBHEXWN~r^W45;{xL>rUeRAhR!M7;&^OL|pSEP?zbOgL z^^rs}%da5@4e55K3DUVKRf^u`dC@E(^^EN0Z!FZmSE&-~Ym1|r-ecRyaiCJ!EU0D- zN8j}I0^&PoR(%NepqKtbyALr*fs28x3FV#EKt`A=d?KfB6DW@PW@!oc);@F-DunNH zKk)=07BdL{`=nQKdl33;(%@V4xZNs&JZ-{EHl8+Iq$l+(Qweq5f4c#4Wa|YpsatM#m`^8 z*Laa7zhVKfJR`aTxt9CMj?)}t@(3yQX%Nt*`d<6>44ILMrRYvL5=~NX{C<|zmuD@T(T}rFr+H>Qw-oaDbT$enZG!<2+f7#&RaU~Bv0|${% zMi>9Bt2yqLB&RxeP$q*#i2`zn(I;IWrXLZjH4eQCQf+$8`?VQ|=!Y#VMy{@u%r4J1oD97xJzU{9h0=?B);6L?6IN7{DL6gR?zCP>8K%@2@ zTlbjb2u|CDwpf6WCr6U12?GO(`SbpC`<1ckRKZ;-$*6jvcbE#RTs)GQLH=CjA&uOCGBcp|o545U} z3T0;mqORWP8;WX#@F;%d9(fjf&S z?7iE`iyEjJ9-568PVUJrGG?BSm1-;Rnx$L8*bT!HctF1+n<({cQrSK#U1jbTN>MxW zKo+Bby9uv?*H)anspfWg=U$R@ad3A86MPh>jgha<-|!j)$E<&FXt~AJXZV}_nk-1Y zvTpdNarh}t*j6zEmdlPGt=ZSg5z$#Z`+hBEg*mzQ+Pb4ipR0!h=hNBthX9qC}Obi|YW}?ozJn2lm9YF@`QyQqL?dY{VMQ#ep`IhGjRMX$q9XLR@ zTzYCojE`#jvp}prB*$l466XeL_gMwSz)Iin%$5H8)3v@1azwKfy?(;V zUQr0mR+`9U7=4=w9gj&Hv->Ci+!^D2 z-buE(UX=nj{e>NA;W55)9I5-qRtY?t*n^88aHUr*Iu7{5Rb@=#T$Vt#Mluw@q+JbN zezBw#*)J-FFZou`ca{!uY@G81VSDN0WH9wT^F!vUqwH7iOmw9?9;Z+&Z7JuRhD5l; z%)_4^Nr-R<4Nr0;ups$QSCr>*y7b9Lji|A*ra5})E!EI#6UI*HC!Je!#=p(*>B22i z>qX-?cNALGB`qC;yYp$$bH76CqAwm{ElC2)UaWnOv z8WrBmQZ7(Rv@ue%2)2R!F4G_&1hy++^%jK|2A$`*MQdN@tcYKvd$R%iDK3Voh6YAc zm$kot&`xe;1}Jn(g5@t>8*o@VAk6oWI+%B^`Vrp2N*qg@V99Vk?|5Klp{`}E^Y~l{ zqEz8r^v)IxfixHIG%%@Wk>E!X8=|aWU#+kILV_h>n4;f%oQDKUh!>vdwk@x&T18w8 z4pwG3U)#hOm`|JGLL^{@~GLCw_zR*(#uYo$9?TIeUd z?%R$-jFfD3hFLdon?ZzE)s**UN{D~%)`CH(_bpxdDmMGr%pTH)3Nz8cehPCUzMHHt zUsJd4HxdiUS+wZ5+zO$MadtX0Gj6s@^^XgkFxUW>b8DU*&3 zeH5jKEjs2mU$VV}zDBwm51W+6m2b$`}Q1?*af)!;V5nit+K z?bj&(HKCeMb4Z8$D&uJU_-1xYOdOeB&zeaBXa2uC_vZIq*S*a4cvB9$8nEorQkixj zBIlPvEe73#i``6c;CMz>s!aMYxB7VRxDVc8pisjVKeikqP`BJ!#%J^hG$IrJlUtTW|kci-=u+6gvAQ>KS>U2zaisN3V106p!CL6WfC3{y-A!l7W z#6a~Jb}#j1dZz(|`v;zpOVY6nxPiRefrA$ZH?%ON-i_NH#dKS&tLi>Wys0dGTk&=l zd#SnX(=@>&O%ijAId`z?6U}Jzo?7GFtSaunFNAzSWK=s}rct~);rWLK2V({I)I0t! z;Um!4?YEn-@GGP9eBgslZ9yP&KOJ%QiiPOhH)m}V+poV35_Q#o4+%>!-b5dYQ&>z> z2;;A~Aaq-P|GOhjd9cZ9P_%mHaD!E4vuO7G71*Ujgb#?9nM9{%9~I97vb1D?XB#%n zVbYY)4qQ>=>n->zpfjkU7TQsFj=GG3iD1Qhinfeh#ZI9m##44~ zIHv+t*VSBEcH_}o$7E*i_J-*2;&cttqS=9UCf%E+XnMq_yV|%c13pcDfsuGr)EHSM zBx1iA+z(8%DUgm>VWO`07EpuV4FzX}9(sybPhP_E=j#6k_TRV&KNW6AL(2(Z%Gk{Fv#kq%I|t4X%(^`$E(q zL7>kd1X0MJN3vjLSH-3j5~)Z8tv@F=O9#U(sv#A3NsGa-EC^AJ-aaf19yyXXCW)Dz z&xxW`2Cb)f&>OMy;xzVMXa|P8-VC(CstIR+R^=y1S9`Z;gp7Wv@aOvV&cFqSsfRbN z4i5y{noc-Y5j%;3J8r>59)_owB-2z%g_aV>3=?+<$F}g1vfL^;I7$>fonDJvRakp1 zOop|p;-4St(CvH=YTc!ts_bLMctrh$hN0-HQA6J{u@k9*<1RV+o5db~K92h+w`tp{ zMxKUV%lJtV>xzw%(k}V3HbulimtgUi`oPcG>2fhCP}}47)E!UykhmXtNlvk*`#yua zv{c`rnI!rM0pwD&QKar`6)wbWbxEG>vQiNRKO1xx8yoX50dL^dXohFw_3-@*U3?5J zy;razbbl6{5(fJ9#uszY7(EZk@)u$*F|;U}38jZd{Y#N;^8V@=TqM6KQA14e?HH0# ziX!iWsiksoTq_3c(a0h}r$j3;{Km zT4V>(C8lSv=3Cl_E{@)fP1ROx}MYkVDFxXrrUjVyM{w7zLXMU@)G&?f; zWis)eULw@?#j##*WO3&HdJ3WWIUKM_GR-Z+M)gGitWEpSRonBUy@t~OlbK&IP^T&j zXfkV?vw!|fRC7AD%cHQ)9=>+4ptgV_UcmgI)0J*$G_q#b5gyTTW>kuxRF&6@2zjZY zx%kRpfkvf<)R{6V!ZG)n8{I*8mEsX4Na0l}Tc`V#HG(Jhcb5=2&ejeM26Fbj3Umk# zk)qX2GN^W&%=UFK_O|x}hBlz6W@?x5b#k?W`NO3zmCbF2kux|h9?EMe`blC$yq**5 zc;=c4eJmZ|eIVx4l`Ajq2`J&|mIGCmML$VKjL>;7jYNzXF4AxtiV$x-)&v|S9_9G@ zQ!^PG!sfk3Xj$$35IHmeJ zmmu84S(jIHl8WwSwKv7k>o|TKp|d!4v=n%Vp(b)`t^(Ru__phn&E8^ops!m$aU#2_ zb%koNYJ4Q3Qkru+c=OwEaHc!+tkj}D&|vjQ-2*W4gPlMDr;h%o-_o#5ho(CD~%uQXhKpmK=QzHl{DthOX-ojz@ z%m`O$GS_?66wBmtAM-TBB@~Iqzd1#9e?NsFqrT)dM45qP_~9qVxRYKIobO1F0dtYH zgXGb&NpSbC9@p&}haZ9dsDAkg&X!i}ahVIT9z>#)OH0fULltCUC$5?>s{0r)ov-GD z6r#Axjwv2g7ZPR|jyGbZ>==eap!Utot^8*U+S$p zmX5XDnA@g8v`WpllxK!U$c&uZ^fD4YJtYIq=AL_#;E;zC3Kw}laO^e$$=3aMVWZ^@ z$X-uePOiZ#*+sl*g<8@Jb#?VmoDC-L* z;FN(!;PRjuQD7+dO=8Txh^Jabk}e#1|s%rpWHGd6Ep)IT{upENy#s;SZ&a>P z37I``RtukQ!)k0U0M0SbG4v-T&&U0&^S$YE6Dskb_{Q+2;v<)PG2;yqyG*KE7E zHfI^tS-cGI~tIeXSO3Su!d_n?gN5KhV-HD6S zTNn5k7ea?wC9vKh{&~7Yj!(2sop=0u&gKva#mzU^#ZZs(h$?so16wkgKY^Q8p9ZLL zJFSDb^nx~W+DO&SQ6+~_syfAJoFhpLTRkl3D1h7|D@;06ik$GdZpW?<5dTW_FU=V5xZCZ0%b_L9B@enIiz z9-ERv{?B!z+lMdpk*~h9h%H)wa4{b&ToZ|8eRi5!CH2Ev}P3Bx__dewKoiJ1%jEb zs`a2>CG{gmUHZHp^RW77*yO+$n+FY>{Zwnx7d4k6Re`8UOb`4(Y4YECn#7aMJLUSs zKZ>W5IubQk{3AMEk_Py-FECt6lbY@q_ijH&C2vH0T^TW+-j+o?vjG8POQ`;ScCcmd49gbJY)a*8w7oL5LKd%B&{T@A*%*4cO#nc|tpr0YRF4zbo!J(Le|gF?>~o5@rQ#Z7lIS7xmjgHMq$fk#zW2wkayna~P7+ z)*sxcwzfre%?Q#ReyqEL5M|I{tZ#kQn*9Z56^)m7J9z9uV;C))!3qxs?QM<9gS@W}V3#GgWt`?1C!W0)c}8B$O-1`{uF8W1C&; z-Gi<%XE|1rCrp_341w@JTBUiby8Nx`1(jL%YDNl*nBD_bjOLd-645u=dRn={sq0=s>|4^?w z@VDCtis<_u9Js8*JbCROv(A`0BS+XP#`DB{m*3&s*&|{R_fRZ z^1dM7q?w)Mlc0N-ln|IZ zOhBdAF7sMHFLl-Q8F9qujl7kfk|E{x5!){`lzTm-K^A7y)A@Mx7*ZJK3}%hX-J{0u8P6Kx3y&#y-%Vb{7!w*bseTvV z)!Yeq{UUJL-(OjBHPwW;-;`Z1J5RnU_?|HbN6H1lW?_jV1gNqpYmCoNQ&BQcsr?44 zq(77(M5U&Al7h2mF@B=Rjoy1{~ z4j|sqw}O^xy0XS&x6G&ysZ%}a$>Wg0+;8m>FDM;Urp5bwVc(@5t`5tNUc$c}-4_}xwB2)f#E3OQ;LkXRLh!K)emYwg<@RH> zqV|SbDzC3ew)9|lUe^3n$&{Pfl2zeQ!I`fljMeOji_kxuq3Hv?9ul+II8+zt*YDlh zm>3=D;7>P#{V;olTeGa_cM-&_;r{D!7$ZWq{MJkjQ33?PZd*3V95~;qi_AWq|6Zwl z#iD0shB*|0 zO}y@K|BeZY=qNt=eYUd!bSHU#fg+o*AnAGVg1#S!(|YBzEesZzc|Y=sIGbCjx94_i z^D~bK$UL@FtA5Ci&N_ldA8FOn(!fK0`?)q0TT^$+l6FqL2~o0XRGLP+?J!K?xzvW;&Riro zr)~6S(9aWmqT9!iZV|F;^nM3p(n^BDzC!A)kk|LzsW+08YASY+F>V4ap=O;_cO}o*I0$fW~9o*vOsV0XrO=KDWodNN|U_@GM&kyvEcU_=>`GZIO zmlSd#H$k#%|`~l$)LA(}D-rD%Wuc|maq%2h% zNoX*|)$eL{i1d2n^IL)8#6;863y5$)NVf_v#^+l)n7d1>Yyyf1 z6#az?rV>5pB>`I@T;Rr4&_TIVE%?Zh^zkQT7Ga&Rn999c(wySLCRB6G^| z*om1)41a}%4;H&KCG;DW=)^wj)<^qJQZB1y8SgcyOsQK)9+fHL6Z)hZraGa3oUeLg z@dJe_mbTobKJ`YFebno^4);IgXstdbPdYLB%Y?_h8^|f987cZaSUbO zZKkMOstGShD(4pdX8zXNK5f-}Qip~8F5Wy$>SRf1>?2S8ZGxS`Sb8&R$eJqEjxnEY zZecCw!$LLVg2HN}RaZRm?K#YWt|CqHG|!g+kT~N@B^sCxP=qDuJt4kf$dH zslx?I(H0!f@jq4NGkl+E+BqQuIz0YzhPV#GzzaWfDDNMmr=v>NX>jk~G7#cS=>C-| z*#}Ae(Wa4t@ybD8NsmI-Gc2Ne2JY3c;RqH#D{V@-xiVLYn&|NNstbO&HbRAEw!$YQ zR}hk2ACdD8G6_uP!qc;A%k&d~XXgPa-fd>F_RUoaBUit0-bXz-5M>k+!4gIiCZ;k? z>8wcweoHGit!Z#4^-Bt$79q^_hg0tMF#~;fShY(^v@@jx#ZW>;`+!3HXQ~Ka`+BLQ zU+q5KTd#~|qe4?$YbC)FGLN%HB)DW_s+df?7$64B2jfQscE778!7`M^@xc6+GC7F< zZ5$N{c*?RXzKYbWqcMP0ly?(Q8}h8s8eWe)=5#MyVo0%FPhq9A_&}f>{+x8Hvgz%OMs@4(Z)2gD6A_ljEA- zAj*kpEkI)?9hor|LC7o0v(u7Gm{-~UB|ah3d9Q!bCw`|x_q``th}>MB5*@++65tqT zH`$`U5LLI}%kTJ9>_v6Q8w*i>Ru;niqwkZ)1MRD!g$=yACDi5X!S!4gQi3uBJ=%@9 zbgzYrs$zZGRSUx>pTyE~kL0i9GT=3=-6$vWS+zYqT0svv-lN1}m+|ZR0TY~tgjHGU zCnQKQi-d{#47HX5APC!N@O&4C)`nQ@{_mA(xmd*n6(sor#D0r8?dZi4=%dQk(z@9v zmzP4`72O~K_NCx%q@TClC;oykPbri;Ke}8m>{k2VIm>rl%0KNjLCfW=*Y&;6%Y4-m zeQ#{!2lG&=@j38Hu~>oD(m4Yp%6f10eNoCzRmzH0-BtIOtobJj=x?poJBBO~Ez>41 zm#nve>ux(u1_T-6-?1^oFnG|Fy5F~O(#fuU%;I$9juVFP%%G`EiwTf$nIJc@LAQCZ zUt}a#Dp*@pyKBs%{NaS6q(Qa%-RwZS@gw?%KPuWBI!_p7Dd|M0mvmGvK|OW7phhij zJ$e0%Jy|Ar9v=vs<+JCpEQSVLIrApY4{uNADhYHmbonLRg_g9M`8jpyS~XTYNL#lj z7nnI3yloHL)=3^MA~P#!x8XZuA4yk&o>?069XC^htdz$E39b(xsdn-npt6Ty~AZ(`;5%TjV2Gff-C=rT?BT?!nywCn@vFFU8fqcIpy;BXt|8BEDrSgH}=*IaE zq`;WSg8Q+j8PMLtevLmG;I-wXyZUN*fsgA)A;NFzG-oXR6@~Qc0I5TOrcIC@l@Moo zPLR&{O*R$7IMD_z%8yx{h^3&U#n;4gX^0920SLUY{aC?{A!$(ch{Le8spCi#AZZ9- zg1~r2qUWX>JU1ug&o2(~igj7fQ9Y@%_2G0#lQ8j5DKiOoS9oMfA+y3am%p2^U_>9z zu*qeT0>?l&zUegG<6sHmA7s_HC;o;H?ap_9;Bk8|O8sNgP!|v6>}xQ8?;6M{=E{boBI8*<_Fo-sXop0xBCHWZ%OEME?b^o$XUv^Ruc=e4I-!WWX zI1%~Px3H{(s2;^}bMBxk)d7ZU1tk=6X&U$C=nZ5RHE?kH?-GPH;I#s5oAP`*;!&~llLm4bba>Uv#y~`TA5Dx1DrlZo@v#wYffo9B3K`>^|b^N>HbsZrxEtgDtKGT$D6HgkK|$Au&#Jl{jwZzuE9 zRUR~{hr<&(a+U!BVCqaO!p_7k@biA8-j$DMSmvU($^A-M_ zIQV7k?vi8$rBD^Pqa< zV)(4w9`P;vwpY%AOl51liTGG1RW#yssTH}STXM{~*x?C{0zRyEB3D{$27g*m14%ij zcj=7DUPmI5SWuCWbnx#Dfd{+Bq+(G<`ZCmfiyLOeU0x}9%F488K|(FJqHbLf>Qtv` z$X?h{`lntAU;KK!u(=eM{01!frP?QTaQe9XZbU6m>OQz6X^xxogC;ZrrWuWf7c5PH zUF4Iq7PC(h7<549!ohQEYphVdlfM2!saJ(tGnn8b z2S+|{kNXWjVl8WMMwm|_DKSiTwNL=j3@L?erH#1wj~Z%9VLFD708Z~os}BjY9`r?f z%psoCnjy2KFW+02pYQm~+xrQnioZ?;s+QhnPDd+SEaE!}gK_swJd>;hB820fZ$d0I zwornwJ5BAx0)a%(;Ii~$BNN@!jNI6?kU2I}jj|vW{6HLYlkZxR^dGwBK23e5rpbYR z?uL!(IHyl-rZgiS~51jE7`tV|RD1^qvCol|&Z(blemj@7YkcWm44 zsKbhF+qUhbW7|f@wrx8(wfFy@b9dHLb+MkhT2(d2_{N-Ld@rLxUR@}XCt*6P9K9{< zke9UnTr#Dc>|ss(6@H$-Z>}UU?C8(G53k5XizHa#)TCOmH0Dw8mqdHf6h`86O3NrU zlGutyJ8ffY;V=7S;z7w0Vd;0*DopIc;pEmvMyi8=GPAkU2DzKW_==Rb+7aOs5E0sTZ8Y0{Wg+*uZM-sR>aHyVV^Q7Ff2dNm5W1K|~#|yNh#?|OO zelkd8zix~YfR zTs9nySGqE`r?pXe&qJ7jjKftn}7E(42Q>ccG2xGZTVL{ z-{h5aOcf6Cr`!aHgooBArjZ_IzurI(pRw1i9%*r^8Y=@-vwpw`GIDt1~fkB*s`b#k1^7#D{hE)&s+^pfj1>b6|Dxj=MV1 zZbc+OTh`q{>>l?uP)f*~Uex+nR+SINOCFveLG86oYIlN;rc6gOE0 z6amda2Qi(bl%E-3Ft+%*7$@Q6b7PmZ1RCGT#UCOGx_>005$GiCGGP=m0Sfi)(AZB* z9VkqhCz?!6MdXs7sVKQ_V-zqT9&9iy{G~LR8Gf_v3-onGbBYrPmI0s|h39~#l|T&g zZXDGo$Vfjr;RGxlO!);md>c5ph4g*^d^w+NZtyQW}?XGU4g&8+(c%veEb z;#)*mj)pi+QMZkj2))G~+2tLR9>tkqzRM^7vo*~WYBA-{*uSPp=Sww1Ywi-kY$Cl-I10G1d^!JNad&$(EJc$HYhwjya;7 zHjCeii9RQVR$qCDWj|lr(=b^q&T3-@Nicfmz~tW;?h<#(D&FAcJ~e_4*N(@alI3YI zF*?py?nAq%|8DPoC6_DlnPxG@d?(+u?H`UKAEJ*=3~0zq5h;atZFw!&N|gETyf|LW zo<&=CY%c!KW??fq@Sq}7juc^so|QAU4*3A??+cQZ4V6M%8iaht;*l|w4Neq?s%S0q z5wJ5Juy`F!9Sci3&V-964FWSmv?{Y4^@hM|`03IMisQ#4e32|HE;geWqR9e-{ZtzW zzlKL=Yf}IS(Lx+xc|srqGh#Ezuk1v8G?E1tT|X;8#wEk%2IQO+7;$8YRn>UnQeP`ISYRu`hEIl@4nMI2_MegsuWdWAfcg%9ox zBRU*1L!d=}ew@E-jHT#skHj)c4y94+;_0MD-ZG8Iyxg!xH6_$kyVK!j(b*WGa5`f- z{DEwOLzWGDKQEO%M_y3~JPv)3`4)|;8Nc(knvtl9`f)eoE6PaHLFq~kFFPw#>Kq>WGEdpccM-pXCo~U7v;$Q22>Jm)Nr^DbYS(pV+3+aE;0s4s4?gO zX-ed%D2Z|rc24j&k7?*?Uzv$(dFD771QcY+(K&eB-*caU1#zx!$*8WyGMj(&$B<4w zAt%L@DInF%8&rk7^~5*`4sKW|kdl5>j4Xw+&$Iv@Y1k-&0(OFEDuobMloM%c1;khp z?Bir3Jc;F%xDimx(`)g1GaX{g4OJ+uO#P`3SvxDTkkoZI$(cIOOEQ1WZENaJ8`Q1e28+4BtgJW`wfD%?qWjXcz6$p+ zhcpKx|1vw=XO!6$WcJz0-`KBu^TTjz>o;8XrOP;L4%fh&4 z{^}VpGRxzZ&dWWP&NH#7#R(kgUB9B4B6U!m6q?PEO2f+nL+=unfg4v0W^w9y#J!S8 zKr(H@4g7(Isv7rlotV1`ws=96gH{#2Ou>sQX_7{NGBPxYA#8<9@flwMDYgyYKl{WX?b*KKe~`#)VU?8=gRaa zMGtlaQ7W@MLVtYr2dHzySb{qG4OXYY63Hw48pjPB{W~S|BVYZKj*-teehW$gR&V(GHfGqlP!s+b3B_BdUPczFwJ z;(vt^5Q~AZsznl9t7*;ovNK>0WPbJ9v;cMsUfsTI74q}*g|OE-w(NL@qp)Mg#~nUi zw|IawvH!rjMhLwTWBI>8Fc@`PXU`i_qpl`Z!4J?`SMZOgl=`%~SmSCe8uM&fk+wP1 zAV&oeX1XGq8B^(CW9qLv; za{*$lh)0L=NpZ-?M~`H)G42cICGOQq+i$bzwsaNj6d+Lx`Sr4b_<- zR{B#-noMh_S4D06tqQSRfT}`);~uOCinXHTb3Z@pO`{rcxZ?N~;Y05ep3?wP>^< zcXL>l?PcW}$oZ?R#vO>THo!JIE3F zTYdi)P){h>zgOVD45P`W9s;8WtMZP-(*RXu%N>n7g)SQ>Fr@wdE_`Il%DA!S;lq6s zFt~CQhkp-ujw@5vd^$0PgeY|+R6@RDjrva?D=aK>0(q)a$4-m!>$MV;tzYy4yJKWvz zJl&m(nRBeN9m**S<sd%RFd!?Hcnv`lq2_IexmtVU(o=X=>gODJjAk^%|NA z&4*Z2#gDUP&dK!0=iK1$3O+y8F74S%T4x6pd~j2yU=^1ka4|&%(KVzG{)|)zm%KPY zrQBT}5vG>;T{nnv2GnnFZH|ApZ_6DH59RP!D${d-W8ybd56al0xL^-fVt;|XM)}RP zqxHXj!!o5lCR?6Yb-1jopnv&ipMDB1td$HbT2++!ABXDzrR>k zE;Iwke1z#qD=3k*6TXOmF-A6i_mBg zpIFYnjGgx}o=i@oQ)ky4+aDZT?$^TODxlK(Ntu2|Yh$=?d&F6|F z;qBsPSr85MjY-xYhSfG4N#~Y%zbr+_c+}BX_(5t-F~Cz$txr6_QvZeLu|0Wfs};4~ zJkm}g*gxhK-69yfyWG1aNav!uf;xO-k<8^vf}|zr9JZJqd) z!ig>Qa+BfKPYO#9Ipcsrx*}_M9N~bnC_GVEwj0)Ly~C|J{2W=+gMsVRiRW)xK}(9h zf~RqzczU2FSf_aYd+I_e0h(rB84`E3t~CY_>&Bb3H8`e3xBwq zpwOQd81(|H(x13@JiI1~pK!|;9fXxjF6Yiw<)#4%nF zqZh^Zho+H6s>)}%0|NQ@wzc$?-H)bBbkCRCR6)*h0uV$t%V{uqXMp68IIObAagarv z{3VSfSa|B(Sxs0T!(Qm3g*baSiUoF54-R6F*k(oZDyaIXxVc5ayO`ty)qs^AML3BO z{K%z|2(GFr(?iu{$f|TdI%5|JVAG&=$3y|XJwm{YD03?Mwpu$WXD$MyJV4G2ShXsZ zk|qZAi(BY9N>N!_R>oqPiKu}WuWFZWfJ0a96*bJ<6=cG0g6R9hIjRwRLV)5{fR*z*D2`FSzZet2ASQWX3wIEc zTxdW<7{0&OQ|G3384>2sq$&nEXfDk=^rC;{-5J?zMfi`(hcKy20`+A#ZF|+L#Rwm4wC=0O21PKzOi-1UIvQfeW7dQF(S@lEKYd!NJLhPmdI7h8 zsjSqsQ&YuA%Re3ek;KF|4c_$Q9r2Hs>=opb+uh=LU_^FtjmkG9gcbM6KW1T;HUrgq zO_#E+mew_Ce8EshY)-m3=`9^&xlPCjw2C&QG%u~9DWfm|5VR&)FJci$a9W@TZRim< zIN=7u-4t#tXOo00EjI$Dhf23K=)lmlkpkFRAm_i=@w1#2tdrkcS!1n4WNSgC(KIT5 z3ZAL>7akFZYaRO%c>X?(1(O2j29uAW@`$jxZO-jYCyYx^!qZe}EVrAjt zdNS{eB)rbwb>TW#MV=o&JzeuZpreAaGLEm85y#v6N^B~6T65Q&RVyK&sf}*QEwq9> zzW0KC>&qVPf7qh`W3;u7)G)ByirZg9!NXGr9zC+Ze$a*ihwXt#DV%@F@{1Q}UlE@Z zA9MWu#9Cf4W|jXAM4}r2dCEM@Muz`!{MosG12Uwb|D|yupi;^X2i>CHzMvurEk82U zRIE0{CmUEs3!qxx66pg%Q*CdFvZJ>T-f;{4O-=&q9w$gV4mE$q%pC9IPt%Xq<)x>Z zn(5T=I&sMvMOo5p$*332av|bQ3y&BSXgUt8IB`2R(4A$7d!Zg1XQuZ= z*M(n$w6xSjLQ+GA*ax-l@s2e3DKe-jW(BdW#DCz@D(R*S*axnZ0c^vMN~kub;v!gv zbg7*2L^}^*krN^8*{}ZQXw>SzMuLMl-rF<>q0|Li*>nEEkq-1p3jHK&#oGDY#du{s zRO+)EvlrZ;pqE@e7Fu@%;3g{v6dF?M7bt_vu@p#gv#qJnj^(!sM=Fjwx8tCGFcjbvi{DqO`BV)HDs=PlU4 zqLDJ9eta#9lJwi@-61QhDzWhMch=r$$M2ezMam-|Et zWQ&HFkpBufais0kMX&5y&4~7k%vC_zumMMq^J#B}axUR4riJeT##v%MZ8;1&YbRi{ zKBvv}6ucaLX=NB>(oHXyO_<_4ETE^43~C}7f{p7}X6OqToZ z`%qOCE5NUiU~$aFjC+)0CWbHO|-tS(SO4CwIj*^@&Wmt?B`tMEX{vq}=j z5O-_)U38c}^>1M(X7Fb%u9Gjyim<^V<86$CnkvJorWT2fLS_xN4N@^N;Uji7+|5Rd zL%W7xgE7wK+iLSR?pQa;YU$lKpK41rYa+Mlz{iKLrzt4m;cU>Y6vGva|IQWgf}l}6 zqqoinLu33Mfw?9eoN}hlAr0XQyaKd04l_*|t{+hhH4f5zeW}MzX*(JkrvFVr0{+?x zH--t^N_i7}RvRFwmuroOBjy^!M+K8VWDgd}!N9Nk_3Y!JC^uDwD{-9K*f}^D#^Xb5 z0aU!V;&Vf<z9Fs(1{xxe@8pQIw(+v4a_RSv5_9zP&^T*$jDZX#?l8B8Ydka zWX6riaII6Dy{@fZH>_53MziRW?*~54E`p;H(Uk`($wfcS^DdWQfns&SLwx zw3b)MQtVg(3gU2_X>Ub~qgaeXynGN@^Fk?;X)Z*A@5r}z2d5|ex6V%G2yC91iEnRZ z`LL^0z+El0N3!e#0Wz1)u`M@wQ_)`)HGccgcarPrgU1h-XHw`gCB6h{S&yEBiQKFY zzkY*nh_@L|Js4_ZS}1R3!@ls$HC*zRd9omt{~1r_zNvGyF#GC~^r56t8kO>4)LB@i zGvZoN()9Vp-Q@l2273Q!uCtzQp>DSeaExCDm36b@r$~I=z~cx1~Ztk&7LuvsW* z#!Y6tBFVM=47?s{VpQKqr|3SBdZh7GES|GjXh>&StT5X$FLOdR<#O?I`5doaD9hj? zt&l~g=_pdnDebfDu0aH@u7(XQe-o>}&eKbwS zj7;|C;n#*ZNhFmLriLm^Nv4mGYH>(lqpi`M*xDw4>rPH{#kIVA_pK8fQ^0ivAHK_7 ziP`%%gFarmWp!<(khZOEaqo+u#p+D>)4k}E*`F|I-j^*yi2gD)YjsT&Hxi1p>ehO} zBQdmHRH>RryFwBOJkg!RfrH!$UM7jYZMYJ}yJL3WVB;24#My(?d7~Ty5KcCS1ILq{5_*VFBCz@mhY!nWos$1yQx8R^m$_f_h8-AJup)Txf>$LCycnzpA3Zy{oo$|LYIPccQb!a}McnDv-9J4wD`j(7QvLpSv66+L zHRB7-Q$g`&H|%-m+U*7UFdMbX>hSQB+xzXnccd>dRmnECa3BJxXwZMi(mfWAOI#cTv+5~jXPs>Gm&y%KE{i$kcv5=rmLl8A+2@* zQMT?D4FiYTqQ{j$uilgi974sOKYkbaZtG>mtlrfrzbs6$jZnTsbTt7_dq6wz+S%0+ zMdEWjSrHccrYKJv+3E2&d@{oo=`#}zYtRKgo{?C{f}Vcl?&&^#E-o&%kh~4Shi9d1 z7|JESZAS`IeEirN+*(+;0ArUWuGc=s>x;+eF+L}%48*70!Lj}ITVpZ(4U&(mi|g@# zqz|5%1Tt~{!QNr^#~+kEDo(1X&JV9qL^gfl{?WyGnUwOukkEv{^UGZH$U}Fpt(c$i zFFB&(L(2MLEZJS-iLc7`2SH5+8#om&aF=!8Sh{_hg-&yy7` z1!DrS9i5PuePijAb%B;5O zeUpSh@9`xUzRcn)R<;{hjAM92*dG5mLz9i+YeV7X=GZh-f}xy^!=`Y62JhW%JbO6% zB|JIxkm-;_2zdj#c@u=?3?=I2Uj7uHpKLT?azqdGDvl z8%Ik;?T(_u{tG`a^spbAaHDGUS-Y3N)&6AEA2hBDO)xOKOzP-(`*xoZkdQZ00n>3$h6I@+n0J> z4NGqzFVBodaVE5&HM;%&I8SdM=e0vTv2g$LlZb{@;{s{T#z_Num5Y0#4r@PT7NgQS z_|ZN1-o1??TV1R7N-QWiu_BYUEp6{~WmO;J_>RI8VNJ%$iELfa^p)iqTMhfEv)=K(DaiwkEqpQjeV`Q|$pjdnX;G_C;is%5VC z5xK=yC7bnDy>5V_^Vve_Dcwr1g~l{<@PLZ;V1p> z(xfc86&iJx-q+%L%Ik}(~`gq-|G3m-GA1x`hp_|JV!ax_ppaQV2_>A zl)xV?D*F=rM#DDLsn`hNaLM7gXIIFT>K7RK>d*0HFkK4tz9QsY{~l!fRfZXY#yogR z@g3q0Z|3vF37$>!TmDTc*a))z>H^)elwS)y$$}szT`MO9*QnEHo z4FVRe5t^TB%j;?5R8`NH{|4Us@zM0oGoEC~>?{fUA`0VhWSZP_vsz@f@!Rdn<*N=J zX~Qyi`ma$gLe={I zLF$OW;&gOmWHO=luF#_5ICY+UJZixVyCJVamcpk`U)a&Gr~4I(4>M-fbhRU|-QJfE zCI6+MhEe%6glhWo}_fob4w^)_agA}TZb;k%dT}RBp&C^tj zjLGHH>A%Iq>G+j5EC)(F0sEx2mP^S}g=~`VPWQhaO&Jf%dcH+(T1G_guWwSI$0$QG z(p7D>H|wNXWioN;Yd^TKB_te&HRY?ioCInYed4seBmeoigm)WP1jN#B^Jw#P=r=sm zhyEK=y{RL9x?Go|{Y_Wm{~0>^gNA`2=j&zPG|~eaaI3Zb)o6Ig%G%G(S$X7~7f z^glQ{lfOUymitdqETBr?EzRvIWhxw=e{n4x#kjOwt||bBdMHK zKQgvDc62%QNg(3jh(HML%Hg`2z{gFI!Jyk2S5CNlbtOe`b)@B5U!iYR`6Arh4nNfi zzcpp@-bw$i+{{anuQTlU-MEOu|Nkln-Y~A!&4nAKzGH&1@POF=J~9`f_D`?>JcrmA z&XxGhto17Te{TNwWd)D^KOg>o?-L^uJ`FD?w z#I4tz$ZQ!2+ucsV+&w&$LZ7n#Iuw_y)(IPzD|Vykboj6>(&tv`MOqt(1O(DgzrG&E zPgg1CCtMJr5air;dB>^N=w{-uo5@PV;-`S6Qh0intG9r%Su7;2=Mq9d=E&T4snMtx zV@ztReEEUhai1GzB-8vZKAO~0-W3)**>LAg^RgJIE2T&#JNPnnIWfj)gP*4dHhw8YO9s$+9b zr*~rfvENJK>NUENm*TW-rN?vB54n^I1ZOk(aLKgVLi_{mlLN!ew#(_`sWp{qvj8i!kw*!?4ZKs|@jK!{wK(5Lvp>0$Pj#upK_QUUAw(vp>J&BTj80)M&cU-8LR zSE@g)Sh@FYtdR<(rnI&Gk{vGDWn}AO5BC>0-uSYJ3q?|n-NVsitE=e@I_+leQxg-B z+|FJ>hK2y;O?pItR_4;B(H}XklD_BA%QDqlmt67+vza{PcmK)JKHbH?$xIIA zPx#y9*6F2cwOEu_fd@wL0rhg74*u0lS*J&fVK$R%%ExoIq*s`?>0mhjlo7rSzB2O$ zj1Bhli9f?{X)4OmpOXI+U~7H7-v0eHnpPXa+U!JM-|(7iZdj`s*{Ic=PjRp@ORZ&k zJiF&=pm%k>&w~U0ie9!Jj?6DzCk^ zN(tidxD$!5OU$dAwf6K1InwhxEg^}ep_u3gQm7Pap|N;CO!lBgprQKyh}>bgq`v-!07d4LE3?^o6z9i3GW4wO)|J*8jAZ7M-aC`!rdJQ#t~S1_Ioo5b;(hy=!FC9ayc;;O`zE6MY^f zmq*O5yLDQ)R?>|0EltBbuP(42y!NOuxMFYoe5Agv?&mBo@|@$|SF6qo_vo_Z00EDA zWs~v`J3_YiY|j{_5U5?*9nDgn67q#ZFXr-DwTG+XnYnayv4hVBEy7w&*!K0wSmAN0ZXIE*NWYKAjrX)cej1)y-!Z3 zbJ@DyhjI?~F389@pGeIdhw?IJ_rTro(vMfz8$L!ke9f2DHb>mx`k7F6f$$m?VwaQ1 z2Fdk0Z_Kr3YsZvzjmC!Ajc0vaCM5x%531)LdDflDeCFQ+&4#k8t@fMN*F)||gxqTm z(L24nIM^YqYvPnx9LIX=i>Dhbd(9iVRcohJJ5 ze#5TkRx{fO`ibjtyP5U;NYxMhHP+ARe4==FZWCqx)APgqUlYOn&Bh?ib%Ta-3@irK zAYiSq(f4~xRjd#Sba*^f_hO=ZZvJ5S64eFHG4k{MdGwyIoe$`GQn80S@YLSgI+m7+ zBFnIi!}9#;gUW=WGS%S>Z^Hpyx#%U z!xjLp{&@H-;mIpB5(Av>If~dA2uCeZipFUgoc7$SqtxVWwabi)dKZWqAzVR)hL64X z0wDo+(Gs5l!dO5Zx=GAj&ZL)XbS9YfPR(-~daH%v&gTAR;?cfgtj(6i?+;DAyxh6F z`U(eiHsFoQNo6kKzu>(^Zb!Pq2k74*3j#1W?XP0wtrWDI6W==k$4hj#=k^Sn1nx=e z+nFRUwp;Z=7ecwIZ?|nOm_0wO7c+xD`7Uxx$-20(FMPi_ptPspo_*hA=*ILKrdo<)BjQ4o=iW(A%Xbn)+xe~tJ}pmWq#A7~v4U7+yJ(jbQj%TVm0flfl;r2)>dmy?O^cHi7ZQd$PQyOy z`-CRz$7PGzu*9{}X8YsNOz+I`?(<56Qh>@mG;WFSSN6a$XAp$~Hf127%>jMT?D6cC z^^@ya9q0Cm2xoj5M)(KC(JH8_y(pI*;}*^W5X%J*`+9c-oL6G^e&57QSuWunq0~U@ z6}(~39a$%Zk`aZyX2Z({ny!yJ;|SQZ@|?42s8Wk)P6GeeV}iV9C%CL}(@4YkN+N#H za*8u@I9wLBjcsu=`Z0eRYPVPym3r{ePA}FhYXk)#d*!r3 zdOltJgj(L(64iuwLxU`{zm6%YyM_nE8&W==Jx1{Yn|#<^&_dzQ6>RNu166`g&;?Tn zuF!iwsa1d#Ck{)}76Dt>(d2ie?&*C7Z>VhA8y-aN-B!nje8^n=VdN^PuP}+GCd8U{ ziv&U8;m4+JEFKv<GSu_Iti+9Y9y`O`+)z ziLc@H_7z%V#@f;cW5uG+vfHV-jt|lS@Q&Vz(^|)ep0JI@F|6bH8I!aDGfccOP}B3d zafelJrQ=rcd0rzx@rna(wq(k3$aUVF5KG#WM&!l+4!{l-c=sxKKzOj^{M6}q$YbpO zP_=rNAnakZhH~Mjb$>cdZJqR$YpHaJ9bzKs{gL@O)iF?`xMf1I)BlSmlSs$m7lgd;1{kDF6SVzT}yTOV$W z@!D#I#A*mdknT7e``UaK@R?+H32Us7 zXm?3elTypuh<{R)c9=*3ahtpklZ80p~R%*RZ6lawY zy8h#H8n15lI?7W!0B$G(J@r{LR_G@%>qhT3hgt?*oJzdpfdAjvL(21G1YQru=f|2_ zEWy!rwMqv=q>h;R%?`)Q%2r;_R}SeH(=ST+wCO6=cTcwR<)U~i6+0W>k6RYL#{@5GVT%DZI!>z^}OpF@;}*CzkGVgsAI2DgNM4Q83_9k{w}5K0Ps-|_Jc z`OCQGMDA|f;Q95&bibb43f#RSq)hv70?WC$EZ^&`>3O`Ijy&tw++PvFsT7(=%LABZ zb43uo-;61hbdEPQ1m3TUr49n7zOPJd)@#C6vL?qyoHaJFyz+Y9_vwe7z`{f385i9v z=?_d+{IsdBXnsC%%18tnJ%y43=Pz%)OU6WrKw=T`IoukAgl#7OwFXy8F)@j;bL81x zWnB1_G+suXX306%+l`218L~}o9%vYt_&$r}EBus^z5V@@qpI_SY}Hyp1NMSNBd#BF zweii|=kvCIf6tK>Lrcu5*Jx6YKL)U}=o9Ta?QZ>P_mYAXGlIn0$=dS$R&i-1h<6-xh-b4@SGM|7N%t-EfQ~xT`SnT$ zFyr%O7xW+_d3iiDx;(&+u`QNPCP#@IeFoL0-N%X-zdYF)1s4N%DQDMOTW7%d6^{s) zb5wSBAVoNOjYT(|#YHY7+gooOIb?2kL?t~Gk$ke#_X$L$dgpx#ciulvwughiE%3)M zWTak+&Ibg4-~Gt{0dXVvy?!k)7s|3lsvaYm#GoU-mWvD{hA~}KRGB7?P8)fTU=MG# zYZ*etga_7m33S}K;p3&47IG3Y!OEGYnc32(oFSYoo!OcxwX+&};fz3|W{7|1*v2B8 zdhwj6v{Q9%>9l<^{YHgCyUfR0r-s)5DKtZ{b3;5AHtK5}!_BDKu0e8eGVl3xg(AU2 zD|BE#P|`G4s;}qT;1|XpeA)N;@o{3O3<;JZ-YcHWs3-LG^{`*VIrmbOMM@F6-eQ}~ z9(ymCDY4DA*4Y#-mN`O3T7fNKz)FAMlJWCf&*&%Wfbm4?==GJCfPSnUqum8zr+~}_ zqTgm+w>WS+LfXW2=F8u}^@dCO>c{?1Fw)vONDUtdgFJ`i@&ujmub41evxQpf$(I{P z&2CtpDA_+zO8OiU-i$ikg1|y`|F$_LY2qh1STMXrM!jSWXzQWKBq8h%0GHh9Kz1v13y>2le87`e!Y+zXeK&6?WlF4yRlzDIiy zOIQCmvlvI48VnMZdW{N?MBe8z-*bw*>#%wy(Ha-%U0lqj%=)fMA9~Z#WB-N7`}5`f zof0)((eei*JCEQboGf%z-&_p24956eE;iv*f~qP!Rx8HwYTVb?h=S9>sF3~4jmDo! zcWaipvUssTtANfgP-b9fiD2Kg274kt(Op2J|)UCihX(82lubTg{}4jdN)BjNBFB@v8L!nEDQxe6S7IuZ~9?Waf3 zV{}OmJnnXgl1X7WfSxA2mN~dh{a7B2L~+3dZI?QEBalCUHIWqFwy;^kvw!K;5es~NWYgh3K0O^R zb5T~b{B+yRqJt5FWnHs&OKbXsiI@8Q8;mFHo>?#n%^P-#-0ENCg`#?ua$w=WbRDXu ztS*wz5f#ha-t5ul#-Ge4VnP3 zn9X*=B4gT4_c_Sf5sx-;#T&VBBh%uSa8IapaH1u^>YxRpQ=fS0pED#3#`Nj^S+7^V zE~d%QKNn4Od;hu#*VI_wCC${ATiym!`g^&{0_inD%{gk_C{y%F>-kMxfxlqtp!z!NjVGkWAdSQX zJ|Ex`>Vn&#F9vOUzKJHJW*O{l6IRi43W@JwzR;$~ndf*J`=3ScUb57l5uXOzH?d;- zhI?HGhKWwtT(7PjHd%NmffM=gOLM?Qi5$P{)MHO1R)?$)uU@4~0g0SQxnOFx+?-gX zWV_b5b=U639#zfojV*wMFKVYKAyhAWagoTE`dg^=0)*x(u`B1$-+8a0Xnc`_O{ zYIHd{d)osL6`xKoGIUOJ!a406Hr@F&QKC~``|Cf}N488&Yl)t(z@?pCI9s}xa27*^ zYIN2JQ{M=2p6&T?BK7@#B@<(WmqO^*9lD?gPHGtA7#kDO+-R)-ry+=rZYeYjfr55y z4fmTM7=UU&8PolB#1fuD3dZ9+4o?kY#c2WJ0(03nVBxT{yGxEpGzH;YF=`?FqwW_& zq-Dzv?=BkdPJ5w3pa1L0K9UBsd!+Swhce+M^!E=+dI+IGw4IE>8~40sKOu2ze#*sC z{})!f9lIC{y`Lip8teEhE@Rb7;w}<(^h6j@p3m0i^R*2pP>j#+*+b7YWb=2qzF$ep z#GbuBML|9LuMR*GQxxP>2e-lCTxBk0w zeg=gfj=?eKp9E;y`O^n_Pn_X+fH?DSVe^FluKXiSt4^&(5pq{*pbS&E|1V%#a;bmZ(Ju-m3GO^s*s#u!%uL9GgP2=8340ig55h z*hzcz@wVt4&g(F_OV!(EWFn7|Jbuf=wdLC*#NvgP2?}u>XMv#;iB& zU?Nj5hhyn<_-=<>203AAQ-n&`V|OfZL<}oHCFG41B(W|454+ui+>-WHJ21PEz_*cd z^35v5NVq8Uk!!2fUM*z+*0KVC$zy*NJugdcYK|LCRVAD zU+^%7i^nD&;eZ^&>*1b3$|Z>}{yprMp_bPL;ix)!qQdDyC)VFa+7DeiFe)7p9ee1B zN-}{Oy$rTeJTs%e>W-Mlr>{v-4;sf6MDE$z0$qUV(*DV+fi`Isu91%Igd=JqLB$M8=g#l&*8PQ34>oC&T~ zBT!LRk6x$2gRK0z;C767@BOPXGKLSZ^$)niW2T)UtaObZM~u?}-Sr-;58ealzg|RV zau{PX*Zx;oUU+z9Ut+*!fu4gl?BViR1kmNaT)o!-EqzlGl6(xc05~~; zKTR$vb9h`+>Lauhq|^k#;D{Kv8IAf3vsl-XmF7S$VO=K8)Q3MsmT&@)#8#fc(~JO6 z#Q#Y?brYBkCDw+k3fNDsek;pw2tyJhZmVtcqzOy`#wHUfj7b+TRzCW`8M#24tyT&^ z+^$~lw-`IZe^U<=dx@2Li_KPoOYosgOKZ(8mi?cf@;X&u-otHzb|G?gPsu->gpYn* z^)%H4DPw9L()Mi$0ly2Ku|0CK*5J)b#Xu;MJsCy;IR(D^vX|HVivgUkz*z?59mkzK z^7>?ufZ`Q@%x+|#85_&HKS=tg`Mx=wnpexEKiExn{PMl36s2`L(w($f>ur)k&f zvoMd1b)Ij1@;jV1N!w-Ap8}e?!+z+Ordg<2&cRLh(1p~*s9xI&16vUrWGNKc2*7vp zMc$3U9!~&WgPH>wx)&Qa*PU(kHu#B-XscqBVxT-$r!SW+dKwm`Mo^U?mh&KbG&nI8KQNOTr|6*G^3%f5+P|yc939NeVOpxu+eF=TAMEAxunW7HN=?h~@-5hQ>QxK7!Mchc7TX_h>qv7Z1N{Ss z1aEcsp+e{#`os~TIwJM357cODfkfd2{(Jcd z^q(_ctFsrq*5ezc?W2#wWMI@?SfffG_)|DJ0~wBJyMZd9oS9q~|P6%R*ret6eb(C5ZZ)aX3 zenTU1w#O6ublu9`tAxjAmbPNTGtFXw1@!lc%-Sqaq}?AglCT#}7Dg9LE>|i^xKN9L zj$G8%g;n?4=!5y;pnq=Tk?>d&)55W%$OIt&ALiaNsE)0R+QnTq?(Qx@gS$H+K!Urw zySuw<2oT(ZyE`PfySv-%bI$wS|F`a+uZp7Ry{oCNwzbxn&lnSVu&%YUI`a%=cGAGD z)x~T682?MblAbRhXDuG%DZ0{}_to%?r81!haB(`PRjqrJ~Hl@nYekJaW_fStuwBJ!O! z+fZI?L$b#Pjtp+!dDAKkVjZ`y4x)h!ipS&z5_5Rps1LWnaZj~YB!yl*wF#Oas(0MH z`Z9!#t+B~SlRmZJ~XJ z;nDW-n%0%6r=S9kD&1%%1LnB zIQ_5V<0Ca<1YFc2UV|M{D(>S-IDmq)&vw{!y5x@_xPC<~;q4bpiAd;a$jYO$)yk{LwXS zANN<5ykjOu%nSu=X2>N>*!RcLf-^{zlr-jO7%XN>GpLX;S2)Bbq-4*}i*1l=kzlkK zXrXAnjV@Tx4xDb*5(JLiG!<9+j3rlg$3ahHyY|ius^AwTamTt?WK+nqmTE)r zi{NGGN{c@o6fxvzxwjxwzp|jAG*l+L=}D3F zS3JI3g~#R9Nn2WHc%CjAM3fi~F=Z13^YNsu>k1nBDI240-yF@+P|BgMWER=ZoU#aE z)q)E%%IK>!(?uDZGb}!Ve}gll`sz^_RExl8q%V3o#v&BH*3a9++lN91Vy;a_BoAW? z=+h|tshEdJhCTCjQH7B=gd+H*!)68BqT2i>e4BIY0HFrZzNBV$PQl*LC-Gb{0_#zw z5NDitOsNvBRY-+UdXOLfSi3Ptto5)%?%?}OH2tB?M`#N=By5V~Je`c7%u2?mf80f3 zMZwx)!x-?awPs*tRSxc?Pxs8+8*)U;FZ+RDP{ z17q}M03oG#nhna}bP*bj>Q}&K5Ik(;$M)i;lE`jP3qmcF9Kn{H$Zc;GkED?Fm51OlB1FtI?!VssqcfZr3YN%GOIpRA(wC*$HVBpCl6s)Y~Rs;fA5Ngizn2QMAP+ zcg>RjT{?^q8iw0 zo*(4`m{DpYQJ*_x-fxE@YR76pL!nDYRUh8I*dC?HXri{fZq#m7Jt%>A_$xpN9WjM( zxd-io7R73CZdk&V`CP5BHb7c#i}K(HuzuKux;lb-;ZT`qR)28;;VGp5(lC;c2_r>jea?v_D4Bbe0t!W_Xi)Yx-%moDMZ7uQV_H+xK{wlM zP!2RZY)r!>AcxNqTq4Kj@z6W9g`R#Isu#N5iY~*>q6-=L&9c)edK>fs)kDd^wokdp zMI?8mPXWkB*6b_kh3NgxE-oX07q*bl)jlYkV93T`P-<@X)7-W#6bYZ5-G#X7d8XmO z_>tBDzgsK~>l(Ku>5U8jKqza8WvELtPz^rI7SZY|Ld`@Z zCxH>V8AeJ};a1c(aqaDpHd>|3$(#|Ql_^PwE8P)p#rM*d+<(_FRK#jd+L4#BJezZ0 zeXflbq^P{l{$jlNQ`LjH@g+lhW%BT*KJoTh-E!)OYwXe5SoXB(oMjSeeG^UJeP*9c z1!q}~p63E>{R3!h8#JP*mA?VjR#YG&@}g>VidH(%HEHJ2kI(JPN_9|ra+l0YSUbox$dldsJwGW>DI!RdO(9*a z^yB`!kB z9l!b-ay{JKvVXAit(Q>U7vJG&LC113ZJhf?*DrZ|Sg(DR-B>r7tXj2LnT%LH(!3;{ zl8fSE_>ao__xB<${o_A~-v9aezjS+-_51hl(*M$ORBiCXIKm-_SY)uUuyytIKSf{L z{D}QjF{#`(g-69C7MRz{Tq`}Vz2vPKb9fw*-=Dou2KvS4f_j&hLbRK0rT*~{NlDRs z_PFMGyMKwp#KMwri;Qb#+1m*?SiGW0{^qgulvXBwrF!kQ;(9p0dwS@yMF@(jZ+ehnDYX7X69~KvRKHJ-~ zFn#B^2w0A0&S^`E`o%DjaU;i`74ja~DP;Gqcg=S>m6S&8*UpVa_dWPUng499Eeo6R zHSJ7}a*q|)%7wO#d?8V=UX=%1V8Ap7&N{ERg&oZ9KPn6V@?KIX6DK3RxX=mwII)!!?`Kb zS%3=It@ZbYK72ZO8QuWeUue}$o&7n%qt`0L^ck!U%lTBQ`Ws*1eKDz-XsB%N=VPaj zjDCs<;EOr7OnWxm*bl^ zTD{J~2Dc!9DxCogT;dzPd|9^8YlU7t6Mtf!?@pAu-tIAUT5zScVo*1x1X=E>Sd>^~ z<>iY3=5aPO#%fP{({A(dP`bMP6-MvE{n`6|DD@$AhwY4xcm>nUx|#p{=t#z{ zlP#TD7q0li_wl*uB6wq_Rt%?HrHE^({?cK8obGvNN{@E29C-u2!&6W!0B3S86xr%f zBym;`0U7ZJ(>Jc!XL)bCIclcE-v_#d3~4M*8+cMI9gp;XD(8f&?oL?*3$o=mzHa0P zLL*>ki;0W#oUM0=4MJGyy1!$MW^wzMDCFsTAlX=fRw6Ne#?GM%y&h0d;64~vo6%MK z=|1oK)dQWt2vQI9FP_`y(+>D2Q-^F<+ZFYE@9-q**2ZIY?|_l+vugoB;Hi3lhd5jA zh}ma(Otbu3p)irzRE%mSpR#~Os|>{dK1*mf`yvA{ya=(?OgnN4omy!1MzdiW0k^GW z<+sMP+D(XN5C8Yj6I3A-sIXxBHf^z$CYz>PgP{4r$A75G_gCn{7m{-yVzmlQ_~V&3 zhs>VNW~M?sK~y}G(PSDoR8)Wm5&}q744Q5DTt)$D;-lpt8XE!kLf7P2VgW`BRHOzs zu|MU1OnP&&%2a>gFDU;#@az3vB#kRS#BepZBPylEO(+=3x zY_;C6wd=PKhzz{QJY0W%EffNb>}&!>*zn3q)L?8b<-sMXNBKkj{KrI(^Vu?IZ5I}U zddW-?b&Y+lUhc*6p2~4=A%0DLGsesA{=VYxn7UO(1T5z4V<(_|zkhNzcCbes0PE%D z;=_&zl~=bnniMf0eA`nq4Lb6RyG*y;+}o2NT5-b?DTHZufaG@L{(Voh>_+_++a4Lz z(DTCZr6SSV5h_qK*uSzz$s*Ude{f**0_PJ5b1*hToJuxX_JNa_IG10g%m_`V9$%?b zac}Ia;ngwa%CA1gzsdRV7m8FuUHqvF9HkrK$A2r8CbAl3xhA`*3(x*mFYqjxHEqGG z2R+Al%&J{BUG&}2rcwSSczoVRa~Mx~>FwC2e=DnsMqLV^d8uomHYbpZCEk8H5eb4p z`FXuZudN$oHC^aoWgDcENJK+jYL2)@;=!?G_P10w41k&w%k7K}+pb2(s?`9f1zqHD zcqWKFg6Q@yoFKMRD?xd!l2x<|YGU#`I#jrb9rDz)USKI~fYqO4EDo1tcNEN_8nF4q zAc*=S0MIDOR-C|hp{1luMe-GI zy2at9$}2CjEnn{ZpgRQSk0GGLCkv1 zQB!`hPmc!PB1uKULZchXwrmlM!$IG>I_(^TH`P?U6sR$xNTzQ3cjK zvwqFj>yrmUv@W_qY9(U7OpYs`=hK@w1%-pNgH2)HVKyusd&UVxfd%hm@}vISZ0lHd{gG30My zP(8B*b2!D8(Wt58?holEktX5u*j&fOElvoyE0d-?ivctgvjnHdaa#mcr9P71fp-A% z1y#t0V&N>OHpzVbwTmiqzR-igazOFvkWFlW%%^fgSi8xZ?QE${jeJP~pF7POuOaM= zuSpggCVQf22xacZTdBRnyQM?v=akTgCV9Y8&x}zR;~A%*U~aV&Sq5CMN?`oeP`2Lg zZ|)63@iw=!O}L5A=R13kuesZY+9KK=u2gSN2i1fV-r7}5NZ`NO7rZ1d)v0uP`RuXK; zi9g^lzJ{eTe-mGl@b)HrySd1lO|$3M^L_{1S`Ozs>lvbXK3qXW*K&?J#D2Fjo^HLg zwFZZC;UxuUzCAuf3Dv%<=cay7d1v008(<^3!Dk$_s>QU87IO)myWz{dAs?egAJ-2` zxI#JFP399bBPaa7Eg17)(Vo9H)w{lC4#s3&ah^`iG<+i*cvYoVZ`r7U1g(-vzF&_$ z%w7PHFomnfM(5h8baQ@0(x9=|J<{{tFK-`Kne|R1xy{CHB!?z4S6TRC`m_*3UJG&8&;(dZ7K;8fqv!p0V`;uH9Ydl^}qLGpVuSq*+oZ$S1p*S>>@lQ<^Ap`oahoTtXLI;dk1{s7&e++ znV+5VEY`}IR{m-}>GoBbac^xEB$7o&gGll`ZkHpN`GOY zE{91-NU**kF39tHQmo=z_LwteGOlxOF21b?F53G1uLWgmkm2daE1%S$bbJ`aRdwg} zXDs~y_#JCSFs;v$gJ%^=T?Mi!<#j^llaV(4P1Y=NjhA`)C#j4&<{l)2(TRkQfqqu) zT{bHynn?g(>1DvIwHSN$QSjSC0Ktw*!B(|$|P{S z_Ljk6-44gQI{t%`6FCa0XbQkzaJwM1s^Re(tZ;88gt*YEA0XP0H1x&TZJ@uu*weaG zu+woW-Xksd!VFkI(&;EdNoOP0kuFqd(REULTQ7cSJxBiqbCQ1&L3y8g|?KmSLgC#s@>%q z^GZCnP;C;`l-kAcrJS4`mpw46HvX<}$u6m5VOJkrWxR$YT}*#HnfPXZV$aKK;F`M% zBajiUg~M__*z{_3Z*}R@E&I!K%F_!P(nrS79K+XfLGDw6Kuge48e@i?g_styxcqq0 zG)i5{a_C5tQ7IE_9K|Ub@kqBaBV<)U|gh4k3H z2l_oO_s_NMluT=IQQzRaP87}}qMHoqXQR1Nn>o_XW}kk)F@DrG9O5E7B_GgPB<=bM zOYYeM%fpR3O5*pN$B!by^m(}*6FNvd0-b7!caZ|dYI#0`pH7Ps0;WG)4u{3`nb;Vr zu6?sxjP=(LOxwYZ(p5eXZDDWx)9Zoe&OfpO>Y`QGb|O5=`*3O!;^EhFZ-WtmFZ z>qYvyIcn;%vBi@Hoyfwcox!AG8d)VHeAwPql3pcZn`$ZHnfK@lz0Mn2SX{&zY$)b- zO2w{A&T0Rhe&+Zf&nIKj$*bEKf07u+^}AiTRcL%F{{8BCC<^gNYFt_Y{(~ZAio`}_?C0U8h zS7yg_Ng~^ZTDB?(lql6W zYi;m;GIWqeD+^1qR4!5XKub;_V|N}lM|0!8y7Nwi-BPpuv>67$pw}75$imi7?9a9IGIBt99CJa;ZceGR`;oH8A6MHQ z3cn5iF7t5m*mbQ)Rn}re#=d0Y&D4iMZs9fWiy$Zc!C$Q8L?Ce%l*+U+YvOuIPENk( zAdkD6NFE9>Zu|GW4O?(V->_|bKXz!!`{O!pdw+54b-0b>p8ae*v+hjC|CO_IPq%UYD}={X=`*qA3(F;;>Lr$IH{|2i%kY^NL2?yTN-p^ zl|PrNJ ztPPScLE{O~%(aIdD^a*-)E7#M%RS$gW1hq_3)bmGlkyqLEy6fpC-!n+9>(r*39e)t zv@-V0--yHIm9E0@hP3K2JE%J2pZpSUf~48`C8V0<^dO_{yKZ)79_RU5vq>WNVPML*mDr*A#(9M;3M8JF(^g1Nj1c5v!ZO(NUHQD*R> zhVJiO4G-)E9M(w7!5Q^_jqETzKfyHoYE@?*M5)jClP30uOAEFB7rq=%WzJ$Q& zZ>_``)$EvJi9TIREL1~yQTEgG5;v37h%Y$)#~9Al7LBq{Q%(yvx7})f0Ay&U&leQ$ zCY!l{Ac~+pZOCwOxH=JKPpfYG&z`%i%@MSjpPwM_+a9K~6;8CgPX=~u1T&x4AJwZx zz+T{SA2tt44nFYS(F4^lnNVajLbP6a-R-+x&yTn17r@`qy={zlDK5irTn}Di;CX|I z$013P$c&J{@t}}soLKMozUC#cp%}6D>oN93M8p(D)9U@iD0H+Rd*pqX`$oC5ZJ0^o`W0l32WZsVBoY13WrdS?}Z+tZKxJJ8lRhW($iSU z#L3>L&#s5`KB!zQOxJaK#*2gc_hUOd+q{p;vcVkTB4mWpc>Ly2h@HOdZWhbMSTUPy zCuhyDs_-bP`4?|DQ+eo`M=zFsS9VdajIxn z4_@m$!orms9X%{J{-VqeV`Q;^?PtSwpr6}UAn5lUe*@;^wi^0qXjIs&8u}v?-LDXZ z^rPUUMo2b9ax7|r-AQd>d}}SawOv_>x&nELSKv+XS~63DH-%6@Oo+NE3G|*^O`XB` zAv}k@ve4+%`wZxQD~&}@lzRzQSXInZF3^b&s4eJQe!U${UW6o+cb#wYC4M$L<6QRQ zXIxuIWl~eDL&^^|ECk`>XO~?FzvcY0#@zU@XO~KWlxXPwyt&MIGV7WvtX}s0%ioKi zP#D2cI4r}#;3}tZxvOM-re?F5PT~Tflb~bYD^*e=UhjBIdv#(M3>c%eP|jN#KbS&I zz;ct)*q6m^7jKOsFTYu#j}AFNeB$DhG+V@mYXA`_U)Xx8|K5W^Esl!jL91QtUNX5f z$>g`+PwY`Eu;hhF$(P2TjGNJ!q}psNhDKRag&(9WDG39KJcugQX=bksdg^lAt3x8q z_zjD<)idOO5xx@upMjem-b;7@{>Hr6n95fGm*fRT1rM$vr ze$ZBCk4QUEhi5YS3F@VxE&+L*o++@4bd4?t^k zcS2tIscaWXY%$Q+Ln%0Z|Cna7Au1d#e7qQ|0M;J&Dk$RqORRGYp@4Xu%%yL*!6SdR znvW|SnWixZS`dW*z^DCo0}Tlpv7u)`hWm$vQ8l~SyHfCKhmGTjYoQg0k?{HX62uU4 z4y)=>3S|FYOR;BU40JZNZ+82!jS_MwJYMUp7lssau(U4Wz!!2BA|QLfj*wm>8r;)= zvhm~>VILAPN}UU(?~!A`S1bM?9jUDpPT$8>sGG&P@T99R3R!UT+-PO(M@~h6at6wa zkr@Gxh3MOV@VNT&d*Sc_bP@Bu9zdigKC5K!j4r#cj$Odc!12{igIdiHwdNqh?QY-1 z{Nfn{(~-i64Sq;Fg~pUZ5@rA0Nt$pE=8j<97l|JwpG8y|7!_GFEaposs&Kq>-Ak-W zfMN4~vBQk!d2i*nGux$XYqf-Zsp6R@dYJ^*#895MK5^0SnE5g_rMd}a*yH8KF~Cc6 zU>pE;dk1L0DvigSbOA$H;kk3`dCpRSsO)mbS1r6J^>~Rg;0DA=-@~P%($edfmAep) zu=myKg}{@45d zX?yRz`})=#-dNt;>`D&Vnh+7=@-%|FIPZjT$d{;BOXeS;FPN~%&x3Y)Qi1>$4C(9+~iYpYY9=iZ*?)dre#Kf0K)q^?OG42Jt7 z?_lC*V^81fBiIp3pC3{`U-GiBZmBPber+6ey!p|tXMCK>fX9<{sDFD+_g&EVVAQo_h__ANi9PonhjA*Uo8HgI_Hpok1MYvS6`K#J2!aoYh zqe0B*ye;etDVmwlO>|?W&9Au~7W~?jQPxEAvTQ3ko~{=5GC9GLk7hd1-m5hs zzBNXSFH6veywQZD!S)P>(NvI5js~D}#cFH6HCe}Ffk~6Y4d>}WWSbY2UIaam?~Ii? z1fS}EU)bFIw%Vl_E@Z&;NcyeKp=dwR8Pr|48XRGCs3^kb@aPGD%1}^+{ptzV4fj6Q z9y;{mF33Ee%%syA9W6F|{`@X=Q;t3FFJI}KU6~)KgtEU}na&4h7~obMhE z3<3VDAoSU160Zhsf*NF*sgm`pjV!JN0F8-WCw`BWf9-mIcGAjg%}Ke!W?C8EvUJhKVsh5HGZY}MBGS9sTh$l-{)Zsr!Jc5(*qa=I}gI&?vWx& z8d9H%=G}8o7zG9@xAzLO`zic&xYTAonpt zgG6oxx%TxoB8wVef|~7YekgwOls|ocSo>NxU#=D=W&9hR-D5I`PwwF9r|z4idb|WQ zl4-&b=DWm8&>TuFY;Z8tNTWzHD1p6LP|Q3yC~P|vM1S?7>$g8c(W(6iO$m6a*rv-#XI4HKb= z`F&}$LKav|nTPd3#Dp>`TN(A7xC=GGv>Zp?XhbmzWbWX_*)NxO-i#wXV&a0Ay}YAm z+5E0%2lj8H$OtH-?lPd%JDY9cu_8wH?R5gVJ$(C>PggwABOHS?^DV*#lR_0xB;hP= z52uACG1}4;Lp;bcFN&9!x0o+Ri{Dni-a5b?)0F|y0v+QRw8nTn`{V@iv`Im}=xl5e z&hM&7DU93MWeY`dxjcCeB>s;G1mP8P>?Wgi;d~2q^FOraH0s1%dxMV{hdsxPi5n&2 z6%4=}5Hl2pV;ObIqm4Jn5xF^Qtg*@YUMY(<8i?Q44o^TMcGr!P zlH&3lgKw01kwc775$sVq{9RLQH;uNZ=;d20*p)eHBH;TIwz=*nqovz#=-B=UO(L{6cjFN@6*=Zee&TRQWeM&VTjx0KMx-!fz(dw zHlu!6f(aJR{Ly#&#BdK5jW{q0Yy5mCve3(Z*SbTf$>(@WEAVcvwA>fKTXe`fs*oQ# z?*A^fX9pD#|HGK+vD;Or-CbAQW>yPZV&D_n} zWFJ%rYh~)FUwTnpp9pYzO-cFL-X2Kv`2n-Sb{OUXDQD_f-^HWx-!N6mjj$D>{e)71 zh*k|aOtKw@;GjSd5qRo^$YZd5$TB}|VN8rw#izrByKrNFBEBY>&^0z7OcmDmQ=s=> zVN3;i))i8?IJirJtA4fZdeSV^d-NR`uBwRL-?WqWtguyt3bEeu5{v^yBHDrp|GryI zKSu2FANDNDb=Y>m(dAnIo+A|2e`R;&L3j6$mC3B2kZ3-@P)b5oD(vm+{o#+-ZTyGA z!UG&eUWr91gZ6hz>-1%T(EzPzNT{cPkG7c%r^Kp;Zm72PZ#OVN?nAf5P=Fw%u7KpN&0Z0ayJY zkca@@tK#75kh&%T$_VHS^TdPosIy*$6tA0Yh1FzNi=@DNxz{m2N`$Vvfhoizhg({Sa`d}BL>pOeQG>uBGFJ#h#2TMZWaj&vWL~%_ zA1>~2s=ldh_=JtHONNeIqp<>l+$?RS#6p(9r&0BkiouipC)XtcV?7NVegRE|0S=$G zir3}1?Z}rU6>hVYd<^^nBym#X1X;%wPaNrTYTtS9Pz-~@XZc6CLNi^R2Fl_o{67D& zfP~Kt6sFpDjzUfEgesL--$9fzl62(~waq(i7e-FUNR4sSb!D0r5WaSWA!TeMSf{tW zZCIu}8;m%aIHQ}80CBLlqqL4wyS3)Fkpzwth-wM9={CTH(ueQ; zk-KqI6M-d~Y)m1Y+K>zgY{14y6)n_};NvwG|4W2=nf7laJpwE|g^%~z;Gy?uNP^*W zQIdX2*UfGN^>THK3?9yHX(p&GXc^AJS50v*uYSHdjvh~VVsC%4pml6E+(s<+HvTEF zdm@!bKq7Z=_P~=$@hRRYG7Se$y$2IdO5nVik-8Y$J?=v_oykGR#8A1&Mt;6HfNF?piLov{dfksMYy4LeQLq#;&}!y~ z6KWYo;<{s1J>$3mteEk4(jZh0+g0^t!B_u=SH?#RkZ;T$K$(Tl8C2h{jkfkQaw5@wnki z47fhA`)I_IFG0QJfg*tK0TAG1CTV1+zh6k`j@wDgxZootfxHjNIw_SY5Z8fPQzHmk z@MS)m7lcmOE0~?dc-P|+q#U;SQ$>-CvnGl>6#@|0GQ+bjztk8rQA$V(vfI^I{~+Ah zK_mPwq7VH>$y6|~tk(;LBj*4{9ApQ@8sX+Ju{ab2!W|q6mG^-%V0|wF@p+4Xf8jG3 zx-P0yALCORWFR2t1*`OTUW~>918wVGa4YX4w4i`Ul$FLxvD7kb5VHG)@d50b)V0@i!v-Nv#w6^SalCLj1VeyymENOjQTl z{jC$6ip)?jQitR?rkm7?n)+u`+?znRA%!1!pVpHEor7(rw6M8+l3YE5s-su}nM7kq z7)8YHsVq^*5eeH+gCvo&W=7O#m_)oDEopIMO*Cp$^xu2Cm^i&>A(mWJGXsMDm{+&h zE)LxHN9?fw42W;A@9DaIxe$`M|Ku9m&u(}N%g7+kMF}BVV+Mc4QPAKgqx{gRv zA$gbipLQ=Y?>tj-a_uD4;~2?SL@mt$)+owl-;YaIVQWjg`bd&w@)d*|-x{^YyqO|c z9raIzqF9AsfQhZ8pih*4F}~0@7#v}N{0lmUwzzJBE-cN2avQ)wDqSe#&|&aYz(XJQ z2QBjUvlCSO7QcnUz`+%VBU|Lc$niXDP2upIZ{xSGN?ao+r!cTrWubI8JO6P-jqM;h zIXd+Q;mb_!K_!<=&D}ZqLoNl&C=6U52hpB2csQ~f%nnzh_(#|CHNkwj1RvgILazlFfQ5l49aT^4no8g&P(1>L3b%&nciwLn4S#O%|@tC42ac*{U<0-Yj z3?~B5g#is1BrN$0jZ!9Ji@~%gj5eGfaoyA`yWVfR?EF%!!webaBQ?8b zziU2>Hpw?Z-&d86-Q+(4&IiNh zcr931v|eM`nmel-QznnsblN2bg)ELVPwjN&1JmhAl{B+SC1*bwON?Pf5rMAGYLt9{ z{YlU!O}8g*(pGfOe1i{f{W~DZRu-reQsf(5%{D0bD{cZ5exeCXg@`x%)XOzx2%kD+ zL}^rSydFF?`qzD4Tvb@!iI%7WL>N5s`(`!aU|Zk| zY@9+?0x!Wa_?=>Xq0!j2;21{YI|)CK^|p2H(a_+^b$;oVFF9Elq=BSR5*{u*OZctk z6P`*{)N&79Kq^Fd(wgsnOl78sgIgsrW@C%uH5fv#k1^qb zr6++VHj5TE>#x57|5q|QWTlpMe;sJPefm9!;fbo911K{Ni*ohkyB$NDay zH5!KR4kBcA>nTA@;(?2Jb_C5&Kh(tVLWJW5v~>nZ5WcRW1_lNFnCN;rS3iJ>aV}IsgLdzs?V_Ri-`S}WF5WO=Snbks?5MqFWipDWlZTa zaD!_!q+;x6v^rQziipUWF&$_1hy6vi2GVK&Ro1RkF#WH(F4;S3u%&ff;FHZtQ;zwv z7s(7&=K}yvr5ZJVIc@LgxF}zvHw7>U>W^I1ad(iDX#jMPjp^JCF_d)UCm1qD5)}AO zs+17}Yp_&_d<+9acp6@IdeP&3(#WVE%!`qzM96eYgI+M#P%th|CGtLB#e{x0 z4u(V8UnGK4B>lVpd_{?olMJ6vI^x5C=eFOFw zb6sI!upC||?MV_09iAF2k2KF;pkkV@(R%!G?j#DbVGOR$rA}1LgVVT}1y9S_{_E#QV4=pQWhHwm_?_ z@d$kv7-K-%x(4?A^0f4I8A|>D@;K-HJ588qEeQ8`F+Qm~%YS zvtw19*c+(&%ah!4GyYo2aqhU{)vSUb2#*#Huh+y+{p%=v`WSdMtUVsAFw`Nr5r(S2 z_ziBx#q!V38=T3JV#p=?OEY~p{hum8A7D%Klk`>mcR7u~cVJ-Tyo~1z>x>Z=p>399 ze1S(mK;K#h%Gj0B1}EN$si&l3_!+`A9+!QrsT98;daBfZDy`k;guV$Q<1uD*$4Z!0 zieJpXGWvJwRx3h|FovFS26NsrVOjy@DycA3qGTlcXxOFNPb7tR=BSr9(Y@zEVYJ!Etnxgv3Gm5p$_=$w}jfZIY0K`LjVA zA)Z3L;y+fnwa(4H!Mt;whs+4p_L)C9rkEUYKV!yD)#x1Bf%NQc>~-vOYivN%q}CKc zpf}V77$1ZKe8N|~L98k^Yi#SxJ4y7%@BFdL3ZY%mLm*>`lHJNI?%$O*iT+%|8^8Jr zF_yW#MNghoHG=L9n@FrFs&sJlCbhkL1tha1-^%if@huvk7Hf;qeNfNfUCLO80%$GX z1m{nB=#w%zEoDl`m%SysKdeTbuquLu;}Lx0YQ0g$TJY#3Vyok)bXMn!cOK5t zh4g1sZ_Xuruf2CLDR?b~#Sy5$<-{L|hrW>D5PV@oLRXvY(vA@Jb#3;>3N~iv)ZB1_ z|C$VTk^afUrP3MI+1WdzpnnI1Cy#}M8E+3raj-1@JDr@GRp`GD`ro*uR2}&=Kdh8o z6I-hcr-HyOwnGqc3WN^cndOp+p~4?G>d;gK1mYWun$-S_(Un1+xcn_eypKfkZ_e&H z@xO<*jA=zi)d)79C?`a#GRv-{fEq_W&Aw z_KZbNY54~i_ZUy)f6nK%J)~aubmo#K# z0fmKyv)&5w&Kw?|?ul{LdZE4X|GGY!qB=SR1_t|wr*Z(%9vfoleDLlBz4G6E_qM3X z1ar}6(Hyt8w-1;9Fc??+2K}=a|E=*ZcX23!pcWFjv;F3OxyI}eu{wdz{~lD~DztW= z)c?Yb|2>L9<(~h4+tWI&b+|wPvZIp|MIFVz*NoVZoPvUmot%7aq1(*f!G-F-Pjzcn z+}t&B0rqTl=0*K-M3j(-Xk=k3j-0%gPEau5zf;Lm+uTgS!eS>YFP&dnTB@$MvwJGP zF4&1lOe_fxAMx*nkl6GxOYqS`Q6kEq8`yhTKZ+|4tEj04c@` zjK$XGW_Lond1P!X_5TjT&?w@&&YHMdJ|D=tAyf%FsTBP4zh4b!=lTfg7X5oOo;h&~ z1|aTgIi5w z-oF<<(s1yy5^xxg7(3=)hTBKNp{i}jsw5KvN5c#H;P;^WOdTmICdL%U%fk~7*kdFl zC6wLWdGW~(WpY`eZWOVMizTfRr?8+YgB%& z)M}%b%Z4yBGb`6_g!xjg9>OosPD{oXK)A>TkI*WU#Z~z;iAHJI2sk;i=RGMyU)+8< za0-&;zJ!Tu@N3PT|g1ag)26drEa`Em)mg|6=izq#j^UA!48ZK*s~5L)xkOIxu}y-OaBf9JL^!gta?muyM!eDPvD0+0 zMG+DjqHJw#UAJHqJ+x?RSNAhL-5dcP=wO=1F37T1n-RAZwqciO?hyF5;+u@$ ziA3_Wf{F`c zu-KOZhUWJ1*aK4kx9F|DLDgDADxR9{VRA9nf0BrOpO5^=!FDk{g`OB2tyU6p50^p= zciu5%bA6wo@6(QFx|^R>;Sj$(AU--`ESas;+j09mAB7!tHfdg=bNH^RqoGtp?4B&V z91;JMHhugunw2_KR8(}h`c!{=!?H2A-q8lwmi%9DpRMe!+;t-W9~#hNAz7nZSHy4p z>4|G=Qivti<}(pbOB|4es6;$Abm4dP^tH@3=Xv*VSDI~x&3X5b>^=74aJm4pjQ9bk z-jCGF%gH2M9GkbFbtDpG6~nRfg!o?a>uWWom+el; z-8R4L(P~b)dZl8U+XX4`Vx)4@zbD8x2PQMlua7D~J~Kwv$2OwR6EDU;w7K*CxJ>5z zJ0;L&Ks+=rZRv_o*qBzmlyxHO11Cxzr_}Y#bG}gy70>LlgBSWy5qFFUo=%2`_j6KE zQ4lZHj-cTx25b^t-@4iV^X-q{!z30u|dpZN~16yv$JO_{qB+QepWQOKD}a zAr-*)W4Y0ZcxR+ydcEs*hz=W}8tCe{z00Qk+p&z$&&SqDz>{ADfZz&{2^LDcCV6OJ z1z}!Zyw~c{8_G--w5KNs7A(+SmeJ5YOg6;qzfB6Rd!Q6^+Wn0TvQE2L{7}b~_^k)f zzhWY?&P3SQfQle<^0!j{46fOLNzd z*U(VmoAt&=qET=G$v0+s9uX8&a%Cn_e;e{Bgg#z2(&j6)z1KbEe{ZCyJH#AU21+Cy`A08Jh&B+gQ$d1g1yABelN1K7a6I zq13sojxZv!`0ivunv#QSq(^oHFxZ>-^!n|&8S5xyv*u7_Juw}uM0FALVk`nV*>BG$ zap+sU4x8z$n?<%LReK8?-iluzy~mR2l-61WWnXw8aIvtcjy9C;d~@kFD*7i~$!*qK z6W)#4kRA?nFR!onPrmE)3+;T~sco|P9DW!ae)@ECuq*igH22j(RfcbyA_zz$CDJWO z2&kl#beDv5Nq0Ajbl0Ifl{|EZG)Q-YfOI1r`yBjz-|p<}%+CI|4vxk6p7)&ReV+Ti z?kg%S#}o!x)|kI>z*h0KK;C9wT>sj6%YE917`i5wReIXA=M4?E8Tw;?98b^r?G4d9 z*4H@-)S$m(dsfjqvbenO+~%I8op#x)s;c(xa&_vDV)A=Y9cZ=aF@;FwQ_sPpEuT}` zuQNo#L})8#2*91We%&es-W8S- zlxQBss+UO=8VoNtA(~Res6G~7EW#&u^Qk+!D@@7{!r$hs(uG6QkK~euR{0RMIayk+ zFD_uppByVRsGQOdL&9F_%as6YP;P~*6l=>yyq{HKYhug7zfPK%CP?NuV7W?yw-Y6* z^;l=SmhhxuCmPD_$_*i4Y#vE#YS@g4XwLcFDHXW9y0Rhx?8hHpXMdb#sfdwIBlEgZ zDc1wf)Hf&jN^x84dZ*oKQU1HrV%~tWfORv~OBb{8A{kq#?WjM8)hD{44~=fIp7Q|G z?<@Za3@t*ITwZPF@#-|X&|7_Ak;=Pq#dyT5RUPTHH|sSdb%BEWQv3-Deh%>4T%CQ&vuAYKdEmBGLr`1v7zaG|5^=P?a30+y6NIw6fOhcGoKkKCD?eB z!pT4++6W8PzBBwi;1?$Tc%EbL=x7_aGh3?TZMN7*^W@1=^b5fzwO{W0GkgxE%i67% z{_Lh$BqU55q}Cr-S8&C=NT${M(p$)3scLluVwQKXPOX!i)w0OKpVB`313jOZ#?mkB~(U)*;An0q|1($fA4M0Z#4ND3U9fS96K85d+?3EXp*Ph7{9628+ zCugrqh=sDx>fVVWKmH^A%}wYBUa#sb?Dnq1=Ldq$A3#RR>16AQa*mAxM#nCN+!@}o z`UT}8$DeAoMbSw$H7;CW3SXqvz8Inq+m`z~oMIU&T@!RjLpL4ua2^v; zbP##6dTfL3D&pIsCC-8K`je_IR>7OiacJR1Y5@{5*~Ub?4uRl)--OhtEVq+D*Kl%; zC!)tN2%0nCuM9^(SgD{$n91}scI6}Y_A;Bzc`{)=taig~SlV)QrLoq}N8ysQV{q(- ztOdeMjFw6W(aHGyHB+>VdRJ;_#A^pe%(WU zEz~>q|BiVf@JK|*P6}!$2lmIpVYGB&lu^N!`;}KO09EMk=aG$rmb)_EfG?Hq=iM|+ z=k0__Mz1>s?gyuP$4j*6l5RV@DVKHSZ%!)`k4YKFwt&i(p`8*F!r2CG%OM*?oitWm zK4;N^CQxQ)cVzxF2lZ25H#Y4I9~LS3jetCy%g|glBF!sg?n`-X}Kj@_5Ckg8IgRKmCFt3li1Hy!*>%z!Z1kc zM;ARCHi3=Q!r4qu(HCFeo`w77Ye^K|^BoTIg`dI2Kv#?ptd@L(cUttJLt=h^#$n*Ib zsG21pS_jj0VS{P>AFkDPgEpovFRv88eDxEl{4(roVdTNTJ)v9FRU5eexrg)Ts2L+w z^4Xm*VSnW1NR$ZD1v_wG&gAKw>lP~)h%`F6CgYbvR7zx9=X``iq5rIF3m6J~g)nhg zqaEE{r$P|C7jxu=8UBtie+dS;WTi>M@wqi?5z(4NT;1OA8{pVF65n472 zF7VG723|Q;hW)?vbq*#}wKvY4aqc%CM;yS?r9d84Z&@0~H`)ugNg_X=9gY%-&-mMd zc_IJ`+XNHI$_r7fD|uDq`jOG~5L2S1045ENU>A<a1ayH*wOAO=j?rdPZ(iRnnJPK$c5Y-t(X4F3M$QK_6u(i*WvVUbs4*T1Y`+pF-~DEU%;$c7 z&}?}g@O3u_?@!P3ZxJGl)ALgGyKV5-OfA_ih9g-tE|CYcBNF3uKDzpLwGDqX%7rCt zWnn3{-tB~JCgI}c+>{h21NRvwFm_f)ASOty)m(Ez5)>-2>8!0Q*8HE2@Jj`NK08fa8muM zMW4(rukC_Ee*i6`E(M+ZU$v#m%kPnc`6*{x#-q9F2?94cWG+Ma zuF0D7whlZQ&6D@`q$MKg%HW?-%>~}wT}Sk$)GbGjJ14fDr3TDU2!s)%3FXg7%#|DA zR9Vf0f3l-S34g-I_dCX^v{k@*If0s1&;`m@9lLD5LQMH}%8yFgd+>IzM1*XIiShc> zH7tq4lE(b!eaiJK%!1CXI%A!z1{!Yq*>yd~a2w*$*`K(&TQ4Tp;0-x4n-vV4kU1>W zfGciMqA}dl2JMW%+_s>Y?yX|MTf>cz?Fln`+^R3a2_WBtV`igUGbtch-iPy_pphe8!|Rea?XMD^u}g1gxuI~0m&k$j7Izp zn=L-iApYImo&86x@ky-qFXC8KzidyKzm!@O3x6)<>)$ANv>T(Fcnwp!ld}f~1;wqK z9CjWx0LjV%f1^B+54II=(uZxJ7 z(fd&O^sgG$3JNM_JY^7v^aEZ{JR-Gz&B3MHBD z(LG#_DpzQO6es80g}p66d0Z6p8K@e?A(b6OE+ zK^Y7NidxexPk@qToZB-`srf|Kl|7%X&pXXXJ$p*A0qbO8=bRgnlri|oapn0Ke|_kw?l>o=!WI1#5PRB zqRg7Lw(c1g^z->}gF%dhg)A)BS9OML`$nWWJT^pwk zV3UvXw5e@V<~ zlYO%jQ@ZvZ%Td1atl^-!x)EarzX0jft)<5BvB&;A;Z;nxM&P??xI&ST$66_&N2hNj(=Dx-eUryicbx5Bg|5PG`Rt_>XHYuw}AwKa0P2N9rfkMeFq3Utr{XG8Jrh9#J$RN zPOuuUTdmG=PSo`PATLb6M{1pEL&W{ac6N8bp(38zsh&QRLnGm6s(5^{+O*#ND1E6| zjHiF8g8zDOJ4y6J&CBP^4hyZn9LmJGjp+Htz8YEMkRmb>#ucx*77yyZZ?atl5#KXt z_%2rB4O~e=R1rpyV`_4QL=8fvy z#e;px0j63uKLvLiAbwVvq#o6Aju2;Na&e3nnGzsJmQKD9viP>0B?j8$#7{mAc(Rj0ft;})4p;6P$sHC-mK~0P zC?~vmygoqJ-w@emU}#L9H4>WMey&%>=P}Kzn|+7&n-%1uUTygLhQq|1kIjMz*kk2Dn)$hAIQX6W3kXW z7&jyMVGUad51{~9r1lxukQb_ar$`hB#76=oG<7aeJmCZ&Mu}L=1l!jpR^nOgsO(W6 z`{L@Ydf22^TP`s)i0dvmX8X%fX9ejGsO9!cQ2bp2~^jJhHmsg`njA zZMrLlWt;6MGJVyBh zc?`+h&enLx@0Q0sOA#wha$I-&M8;qKeT6DRh0+Y0qL9Anmz4#ob<7M!?Sa zp;?z?7-PBNj@p9fWohZfRPt&c+oPl0WAWpRai?MzyYZm-+}l~?+2_Lfk1tWhXW$v% z_rElFU(s3v%+2C<4FjZEaV`9<@giB$amkR(CyS)3(c~3y*R`>jzKHB>ZicdRhTy)N zdZh$d6?ID>1ejM`o}fT7Zo6EBKE>V;yAAtGZLD1Y20)0{+wAxe(o;eyE>2z73EdLf z>8s%$8y^;z!7~e!pH5Y5$o7j8_naxhaR2$RU*1WU40pk7p-TB@>&%pm4Y{&oq z9ANx^3poD&_1`TJ=)~xb&xgeJt@a_^VA@A-z36e{qHX8kAbsWrEGLhLR^=`)T-|vZ z42S9(8k7W@AAvlcYF_{I)swvki^|xPaCq2<0>0`45|vIzy2mzEqk$| z`6%xm)q89`^Xxcy`sW-ZIETQD{a(Dea0H({^#ixSjyY-N--oCV&wFLU!k|(87}z{Q zq-kS#C-WTLL7j`xbl+x}#A(Wi$DpZ(KrvitDh2qj%rXhD{Xu%)2SBm`G0z(P_97SO zJv}dzcwLF(n6)69YSPCi{U7AcJpAvjcAW9tVLS>Nf()>#U^g0!UIq^3ByPtP!|mrF z20ikf<)Q#cgv^GyS%Gm#0noA?Yu;X=n*uj4hr?k$nEmE}&IJemWWxOXJQ%5l9qE!bGmtNjI7{NPF(+5dedo9*$Z^Kb|#SyWXy>YZ+Xtk(gCfV@ES&Dz?Ua6Ge4PHA(R$kU)8V2^uVAUW{@l)Hjg27^Pm zBqaYr%GUr#1Kdi@mmmR3p37?g;xvL``+m<&*L6O-jXIi0N2bp_?svX&ZHtR(HVl(~ zNqaGaL*c*ft>!Cby^f*Cuo$7!m0zaHm1?%zx8o-ufs_t7n@sNspbiajf`~MC;>M%Ph$f)!XY3Kt47RfsD9qoxzARs0|*s{=F{8n zKajP1R&?6i+uCOKh|d-J>i6F=ax7Ma#4{_b_f44ePs$uS3kblWL?CB_2|b`9M3dB@ z0gFNb4lB+4!$X^XgXzwlu&Jf2RGyl#P7ql4Cv>J#zw?>fN?rWc`1cqv)7`H=U{r@v z%%I2)4&oZD63PIo#HRfbh<|+^IP{rKLDPb9h7I$ByQ70$&h+!S<_OO2+G!Vj6bozO zw=M~LvWCLQTD+d*{Rk}Jxn8$|vKLlY2ZFZ{t+ZIbLW6p4X1~sqzu$AM%e~sD9}!5Z zr%ZwQ0q(EIa@`nOreFZxYp+pbl>;M^gORhmgEB5i^9~1gRRXL~R>-;Y=CGfKr>E)F zY0%p5ZONxcPb)tUNYW$j?d`?v|@oJ(Z#QUuGd~TwNU< z)0JhpPINnECue8Xx1IKwk>EV&ZP|clF~0a@yx+(NXi2yZA+htA+|b@d!x;ZQ6(l7M zQURz@ITLqz^={7G4+E?I+g-0Ec4uej-Xf^BP~7hIg{$UJWm*f4d+|GZPMY(NBl@;v;yP{$)IRqM#El#3CJJIHcx274r6Pj?s& zVd5F}p)9T35ii_RG+w!f?QPA&LBr``+j$^WDc}-)c=C^X_uqexcUZS+Y-}t5o?M^{ zm6&aCb}rvYN!2opM*}-!zX8}H^4X1Ldk=CYA$c#}nkgwOQx|L2g;Hi)ElF1EclIgg zNpsEC+P>Fn@tQd1oP1PcJ{KgL!YK>Nz09k>FGl_nsjeT4AD*4%0e_egkkBJVA@;w# zq;gD{-e#JK)%e$?+~GOVi@q{+%L&bZgXD$gwm{$Kx|4(S60NHd<(~ zR!#aU2Oh@)@u=SnXAf`M!&@hbApn>>(kFk4P4{L$Dp#67mD8P_?eo8NASAJ^lRWHW z8*Y3@Z@^v00)xCD!<}DuyF5QsYbcm>pcmCcf)w3gfH?~2J(te*`0{hrB*0tOb;1E0 zQ`_@f*fU!OJJkaq;GM7^X8f6DIrpyjfOJ0%oDT4?30f+*=hteB8R4LyY7Hap|4GTS zdjY@~BzEsRom1ddaU6+z)mxKvFj~h`rHlQ;Di!gK)vlo{Nm)%z zJ}gEB;B;#T+D&PBz*aa4pt2uI&xyp*iQZ8Dub&nM?9<{R zvar-^Q0VnOV-^!LMnP#dauen=kktD5AyfnC%;IHU>V> z=%#&;3-`wC*Xuh%a6zp|3o?0NCVM&Pi*yzf5I{Fkpq>2AdPX3Iw&g=iUgL-EaI$|C z!hfr`97Ag~E@TF3{|b0O>#(^*8nIjSn9x@?8V^~ihp+GcHghcw2p~We5d7|i0nxCW zEe}d_-!}q2yJS@sGyX8k$n86|3hR4P`bX%%*-{)d^YKfl1PnsPgK2rX_z78A*+w(Z z**rjnDFvKq@(!BskAW+28DQ;6pE=d3+IPII;YjRZeFw2XHzpw9;@5!RSYKWic>1)u zrbB+8utrP+es6fBx0iNkU}7N50$XF>*mQxNF+fzb_}|)-6?&4ciTLdqt{PA*>)EgwI4O zBc02Z3>7tSqe9025yl`Iy za3WhCiHM0PF4UuM0?4~(N2Lt;)a0B_?Rjv#8?Wo}S|)H#&bzFe)-vCzmKpb5V)t%a zqI{W~Be`xi9xXynW=-}(sUZ#bo73+e9<$3E5E|_oR$59X^PK-<`IobUx&GggBnyp> zF<@E5?&hj&96Ok8h}3&A2mWW5n-c@?a%-Ga&01i8fX4dypn2hq^`ee)jW&F5 z{Uw-Q_cLos#WQDkTplZg;9DBHPQg@HKmA(g_^yxFr2sXPq2*w{DhxQ1$b{ez#kW9n zd8%DGy!buV$g38VvRJ=gs=f?9g^779I(5&& z;d@X>Ma3TTmcE95$i|;Pe;~R2zMon&lQBy9r3k_`vyp~FV!2AXg6tkDSD^w1;2kdjvhAM=$QXgtI~;BFr4$; z^`b8NVIe(y`y)`QJp4W9CBa{c|G5jn!Klj?2x0_#gTYxj;Z42a(z3KwIGFUHr~dA7 zDQReDlkoxUFhKahH00{$rT~~ph82EI?#>G0CV}g9c1Hb5nL;9)7eUz$cQ;(FzXk?U zf2e$iomeCKqp(Xyw<`>RQMibL1u>7i`%Lu0#8^;l0ID^M_0{sNI^$WwOXhdsDJdx? zKq~0~ie12k%YM4LL`6o%9~>M?F4paJI=MWx`DcJ=?I1l~G>ljd*dymH%JGT$1~dz{ zwF!<_%OJsU9dx2<--l(;JF^+h4AK4ZH9EZk^yZ-F+sjciThx>v2Qx$_y-h0aumM^Qe<*E+SRQ6>(K5@`t;4&BKZ`S*$bgTLxF8!ly!agS zg$h_4Gl`7cjDfcZrB)D=bsVBE=oZAkFw=!kJYfwA;$qBJfrxjVA8jZH{+ z>F9N+1Q)rmc0n1fwuYlDVz&GZ0-bWJ=5m8@^_&Er? zv)SvUE^siEsZvV0{8}{0ZhL)O$M>L5IR(#95XRE zs43Oj?%SY(UDo3in^w@k_ZZ(dBmvd*`4i3%P^y;u1{90o+c8W#sl%3d5f|{{bu?M> z!yuj(0}0*ZSt3NevtL>(yxKp#V0WWT<@Nk3^g*b=tH~cmXwFGctI&lHXw;bMhEZ@C zpIb)G@;x^_)OMAbM4$tc60mrsln;-Pp#B#TLQkh><(M{`{WBh31JL-@~&AzJ93>9Tb`&)GVV%j%D3$-hj>$k0$OwSqtXdsM|c z*{I$>*O3gOir?s8s3pCz<>p`Fp0P(KdIt_wj=qB@T$G#{_gG16u86Soi*UwSE7p>f zZxsO*xHc-V=P_1b6N>L1%}?N-JRO6N<*&R8TNJVLfUf)w17b$PXZLzxO4qWvq5}2f zcSWtc5|v_FE-oG=P~G)vPi1=2VFwJR@QIYR@X14h;Xrc_W6YCqdk8R;v>YGrD3|GC z&o+Cq!?qCce2Vt@cDG41RQ&fQuP++!K(A?8NPi460lD{=Kr@ia z>-h8dx>JgvK=kjYWB0mpyv?;<9Ea5|M~T08ms1Dd#cJp_o9NkJzIhW03wNDuGBz$B z`dOkq$UJCh9q(SDD33Ll=EvM^u_%k>NVmJYyPi~ETd$zM+r+YC=VTjoQt{SCyGN*^ zGj(k(Em5)MeBfF+pX8o6w`?aWc20oD!NE@QWZsS)@C9Q(w#p`4yvQ;sorAwyoSz*6 zw4gYKrk$9{_aUL7u}2R_)Ia2qa(AvKxkR&B7$hR(0iMlB5RRC&yUcpuM-gS+QV7s> z$bf*<{w3fWnE&40Ik;jcdTmoKiC47TQ+xm9h2zfIh2>XFZ6dtH22|d;WS7TA*3q*_ zGf%hAI)po;Rkb;S!$R@`1Ci@hUn^8}KAz_+O-Oj2jO+32_bNRD_um_40!*>s;J`)} zOR7Rae*52ikjc7rr}FKzR@n}FBEh3uq}$ZGs`N~M^j%lcDLRg`|0slHD>nlubt%jA zRzESQR3b2G^YVWbYm(lw8@~^0d!ygMqg)|s39Q($Vdr?JP{CA%h&DWQqgQ)ql*fQh z=^W6aXYBAcTfa2r@Ve~o!tgzsw`KEVonwh9^C=H#AFhZiC!n+ieCw3@BVqd|c6Xs6 zL^kC#a!J7&X=^t`?GUbTswkuE(B{$;{hsf{L zeFlp?*bgy0x5q024jJ=OciOFUXuLAoHqXJh84-;qf)FcyCU%uOW^3wf%k>~ z!|HauI6NDwzf#70frIq(w}GVw^3ksyL6O2g*%|$MhJ_iV#C=%g*$WU`8;6YAY0h$^ zvT+`Y#WTns4PSd<^;%&fMnPTOLeJ5*-Y+*HZa6edjjgVEnq2nl<1(N4+<6`_ne&c6 zOhoHqy?nbePHe9`L^~xAbQBcZC%WT=O3e4LMHEPR<7MZmHQ+>64Gi>qAazd6-*`RL zb1EtpdTD4Ofz{pJGu6+3FDLYTjj%+Go%U&+^y5h}c>Id5n(-nb`dvU!4b)y*Iy6tJ zyQHF60;|D*4T?+@-zevgWMrAD3?5&ac=#x!s!EEB3{fO4bUG1ai`fb>j#`Rz*~$VLMJuJW<<4&{Spnlm;2e2}#?~s0 zQC*W;mo;zAd!yMaVNU!|Vd#H&K-=}($>GublJP_&$UrH$&?)_}k0cBI?>Nf8Kf8*z zJp=K^^^ajSR@TevKsQ&|?~Wr!4}%!ibjIWVvk%Sv2ZwP*78JBrWudbh{*NXSH(9ue z7u11ej@hXa4VBTvxE4;6sR6Od0#W*6#z+rPD=15G{+{A?iUx)SQ>n@==!q)C{#tGQ zn&BIR(pfDV^gFiz$bLZPh#;LDY4*p$cm-wUSYB1AkP&EPX=Y|-#{Mwvm>w)H0Cbal z$Z>BpRWkOa3=C8Q(4L}&1>-tuk6bFZLoN_fMDbHaKfLDNx`Oz8a3@&He^!Np_0b`A znI;vh6?PkM%Ap~2q zRj+zU#Sjkv6cagI9_K1Y^n*$tD6T}wJlRrzwzrEb#HRT9`fgvNM2(R!uP~?=l8YdS zjjZEvNc5&wnvTJ0TGQ=uXZn|%fiK=#Najk#$8C`69sODBU47%)$Jx96tU|&X+S&R6cG`l zxxVr8L>lJ5zmouLNbxh5p)|P)@yZYY`$vpN6q=zkXq2RYmMgklKu=q%JUat|!{(~l zxNk9&@2x*NvMN*y-hK=Gc|dapz)|nm*Hdin_@NSH?Ny54OeDz za{j%Uim~!<=3AqFr*`R6Jrfgg%-Zz=v`9Du00Wza+7~wd$tAcN&9C@;X#eFwlqop~ z>$XLk8{u$WR(PB4x}>TovygY{nxbJ|E;N)s)Q3704_cNA%K;LOV_dURyM4UNvbdBcziJA^tHaVHC>D+ z*f1y_8+}vNcCKG~xfib5@6BCnS zBEurVks&1|-BscoE!N-wjJDFK{Colt;csJsD+j}N_#qg?^Zj1Jd>G_@^Z0N6%|whd z0UXl4u#mdDx4Q{r&XtwDo~<)S0;c1V)Qvpw!0_=KJakbjy;D@*!;fJJ-x zY3}=p0)=FlO}py?6(etz=|UPHk$s48@C^N2)&suPsZa9Q{*;p$QrbR4UhZfpbf7E8 zs$iQl9}YX=Bf{ta>y;QBW5Gdzxkz6sGzJ;i4z^dMZQq%QDVSU$U&Di(tr)|bD#tu)MV*l9`!#OzNX6BQE|r;xd(UIwpV*L=XJ+tl|gVq$pbm6qk{a z@wECt7%RBN#{w=Tq!_7qxqHP*Z-WmsR14o8C0f4ef8+Xmw$Rsi4+&}$el-7i&+DF9?RA}@?TafGu$*(sF&(3W`r=EQu&ogLvHP(5TM)Cz z$=NwMW%kG4hvaCtIK_E*+$!FN0|-Ly@(Gg%QGDuuCJx0H%FRR)mhn zC4Gp5U+>gZJdmb#gl8uk!tEJ;F+L+8QyNIB+8WJ8jh(zkS+k*k2KXOD_v5QsMzaX!p!aB13Gc zxY8n#9LV#?{^=J|mf)~ieb8|}jbhUmwqsN{Z9muQLCv@5Z8~>;{I3P< zMySqy3XWFZ4ksi7Llu+?z-nf@OXUF2cv|40Wl3Q&oJN^JPdra?-E|hLO@MfU~JS5x>AV5k0Nr0j57GBXYGj#PtOOtedpPkd`W|`X< z?+oK?ZRtm`-K_A<$^f^+t4)aTIQg`0HD64~_0yS5J zM7Z>wrL{FOJ!n4FdtieUg8mnt!s|f7Ng*U2mDLGGt-jyAkR~@(OO*YzT`y&>Y`So5 z4dKfD(8{{_-%tyCS&!Cok?_{)bdVnQm-35OmU-QFopu;B0daIP--V52`GF66kVP(% zUveqCh*%eOp^QxnltWOLU0rdh;xUUihuL%k%I$mCJ@4+elS|<=pN7&&;^UDtR<;J!+NIuQJ}I(Vnc~jg-y1$c+r8Oi$)IS=EsQqN+Q}b;uqP z^D*-c9;eEVd~RFl>}MTVZIz7(I&-$d9NjU_bBQ4i&2M?-?G?({^2AkgEf*y$WF)xM zDd&pMSWXODgSnlgr}>jL|NK(jb!eXe$gy(o;B|6=rY{;b#P)fF^X@$DP^zx?N~$eY zfop||VvTX%xUIwPgqVBxeczJW)CujQJ&mz*9%>-2>XWs~mO?z<{+8tydhGgaVE76*7x>O9` zklUO&$bM?D#`n;?w00&Vu(PSG2^65Wbr?DG;Lrqe?B@HG9p!W$&#Ty*oU7)30-z3z zIT)-n=vKLWC{ke~c{yeSFuaur_MCf1LOmKJJ_pQm*6ToQ5m{$N?FmSezo>f-i-M}R zS!v`wKe%b>0fP!yKGclgD$o}%Z&)p<;K`B+XM!2v7!rG)Wab}Ak>I1HeCoa_pyoY3 zJj{7Qyr)s^!MYBlY1)g6U{)==81XwCD7vT|cZUzwC3G*HadvZDgoK8RqZ{p<6Z{eNvdy*OY9}kACn*bEPI<%Z< z@B38_MJl+j5srPl+gBbZEi5@UY?BijQ#h?lOP=>}S$x*;BxfC0 zpTT#di|M(!i!<(j#s4`Wn3d6QF~tbAtyk7g&B9|P7MV}#(v<>r^Ws@OFeSL`WdSbEFE7W;uC$6)QNE;+T;&Vl1LGydMk>V@2{EKx@X?n_h;+M9dICv zCny>+WToff`aCRZfZvK4Kk9prjYC8wl4Jj(0QHMFv=}b4d(E)ak#YZ#u`}IwyyLRp ziQQpYLP`WWb4}V2^G#%n<_7(N=nl5EEOViAiKL;e#AF2NyBB4KsD!SjK`~ZI#h~B^ z-HV-=$+U)o9X4rm3GowWY9zV|Gxm@QbQEvGFGaND;;d%bIf#(%HI`I5`fCZ)!nqe% zGAWv=qj(v7q86rt~r{<}^z z3b(m(EYF%O8)dNaARYfX4&%gYuKDI&igyhAnYbLWbM)$kSQDGd?-r&6kbPdS9b*~u z&v2g+7KQ&TQB&LZONA=_Rvix6=2ww$a`hdkOP6{Kwdil_6}DwPq9?71Kaet4k1vcL zdvA0ZYYl8L_|@b7y?>-aYwyM9V*KUOeYc3F4K2RW>EHqG~s-5d-peh_}9 z_nY-mbltD>!enDdjU9-wYIBd^t&d6l*Sh+l@JUwd^|dKXHg`pmOm(n@q&6ZHCp8sjc&@lKeP=RU!oLP zPJ~+`QjFz3)?QUexc_Q4&>Bwe$G{%v`Y7Qeg|RPl(Bz0cf}fVh%5RTfS>S8imoG@5 zBeVE1tmX1_VtqxIuXrjH?8xfAMP|VhS{+%l>HYgnwFPE_(c%PaROi}tDpP!dVM)<7 z?Jmt#VU^ZTsH0mU+>_WwEuU_#%tIHmxvK2jjS9C2XCEYyZ^HNIo!@=XD2E!q8^77I g@_u+)*F^6y&m`Qc+<&OcJOV!?L}Z0agml0D4+1=SBme*a literal 0 HcmV?d00001 From 43300d43ce653a3d4aba6e3070b9ceb700f46fa5 Mon Sep 17 00:00:00 2001 From: Gildas Garcia <1122076+djhi@users.noreply.github.com> Date: Tue, 9 Jun 2026 15:49:10 +0200 Subject: [PATCH 054/134] chore: consolidate `useAPIKeysQuery` + `getKeys` into a single `useAPIKeys` hook (#46761) ## Problem - API may return a non-array shape that can crash `getKeys` because of an hard coded cast - getting API keys is cumbersome as consumers have to call two functions ## Solution - consolidate `useAPIKeysQuery` + `getKeys` into a single `useAPIKeys` hook - guard `getKeys` so that it doesn't crash if passed a non array value - update usages ## Summary by CodeRabbit * **Refactor** * Unified how project API keys are retrieved across the studio, resulting in more consistent loading/error handling and slight responsiveness improvements when showing keys and related command snippets. UI and permissions behavior remain unchanged for end users. --- .../interfaces/App/CommandMenu/ApiKeys.tsx | 8 ++--- .../interfaces/ConnectSheet/ConnectSheet.tsx | 10 +++---- .../interfaces/Database/Hooks/HTTPHeaders.tsx | 12 ++++---- .../DestinationPanelFields.tsx | 6 ++-- .../DestinationForm/index.tsx | 7 +++-- .../interfaces/Docs/Authentication.tsx | 7 +++-- .../EdgeFunctionDetails.tsx | 6 ++-- .../EdgeFunctionTesterSheet.tsx | 6 ++-- .../Functions/TerminalInstructions.tsx | 6 ++-- .../Home/NewProjectPanel/APIKeys.tsx | 8 ++--- .../CronJobs/HttpHeaderFieldsSection.tsx | 6 ++-- .../ProjectAPIDocs/Content/Introduction.tsx | 7 +++-- .../ProjectAPIDocs/ProjectAPIDocs.tsx | 6 ++-- .../ProjectHome/ProjectConnectionPopover.tsx | 6 ++-- .../Inspector/RealtimeTokensPopover.tsx | 9 +++--- .../VectorBucketTableExamplesSheet.tsx | 8 ++--- apps/studio/data/api-keys/api-keys-query.ts | 30 +++++++++++++++++++ .../iceberg-wrapper-create-mutation.ts | 7 ++--- 18 files changed, 93 insertions(+), 62 deletions(-) diff --git a/apps/studio/components/interfaces/App/CommandMenu/ApiKeys.tsx b/apps/studio/components/interfaces/App/CommandMenu/ApiKeys.tsx index d223aa14c4b..82fe7b2cbb2 100644 --- a/apps/studio/components/interfaces/App/CommandMenu/ApiKeys.tsx +++ b/apps/studio/components/interfaces/App/CommandMenu/ApiKeys.tsx @@ -15,7 +15,7 @@ import { import { COMMAND_MENU_SECTIONS } from './CommandMenu.utils' import { orderCommandSectionsByPriority } from './ordering' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' @@ -31,13 +31,13 @@ export function useApiKeysCommands() { const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*') - const { data: apiKeys } = useAPIKeysQuery( + const { data: apiKeysData } = useAPIKeys( { projectRef: project?.ref, reveal: true }, { enabled: canReadAPIKeys } ) const commands = useMemo(() => { const { anonKey, serviceKey, publishableKey, allSecretKeys } = canReadAPIKeys - ? getKeys(apiKeys) + ? (apiKeysData ?? {}) : {} return [ @@ -127,7 +127,7 @@ export function useApiKeysCommands() { icon: () => , }, ].filter(Boolean) as ICommand[] - }, [apiKeys, canReadAPIKeys, project, ref, resetCommandMenu, setIsOpen]) + }, [canReadAPIKeys, apiKeysData, project, ref, resetCommandMenu, setIsOpen]) useRegisterPage( API_KEYS_PAGE_NAME, diff --git a/apps/studio/components/interfaces/ConnectSheet/ConnectSheet.tsx b/apps/studio/components/interfaces/ConnectSheet/ConnectSheet.tsx index 01e5a58f318..994371b3b29 100644 --- a/apps/studio/components/interfaces/ConnectSheet/ConnectSheet.tsx +++ b/apps/studio/components/interfaces/ConnectSheet/ConnectSheet.tsx @@ -12,7 +12,7 @@ import { useAvailableConnectModes } from './useAvailableConnectModes' import { useConnectSheetParams } from './useConnectSheetParams' import { useConnectSheetShortcut } from './useConnectSheetShortcut' import { useConnectState } from './useConnectState' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { useProjectApiUrl } from '@/data/config/project-endpoint-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { useTrack } from '@/lib/telemetry/track' @@ -159,18 +159,16 @@ export const ConnectSheet = () => { PermissionAction.READ, 'service_api_keys' ) - const { data: apiKeys } = useAPIKeysQuery({ projectRef }, { enabled: canReadAPIKeys }) - const { anonKey, publishableKey } = canReadAPIKeys - ? getKeys(apiKeys) - : { anonKey: null, publishableKey: null } + const { data: apiKeysData } = useAPIKeys({ projectRef }, { enabled: canReadAPIKeys }) const projectKeys: ProjectKeys = useMemo(() => { + const { anonKey, publishableKey } = apiKeysData ?? {} return { apiUrl: endpoint, anonKey: anonKey?.api_key ?? null, publishableKey: publishableKey?.api_key ?? null, } - }, [endpoint, anonKey?.api_key, publishableKey?.api_key]) + }, [endpoint, apiKeysData]) const availableModes = useMemo( () => schema.modes.filter((m) => availableModeIds.includes(m.id)), diff --git a/apps/studio/components/interfaces/Database/Hooks/HTTPHeaders.tsx b/apps/studio/components/interfaces/Database/Hooks/HTTPHeaders.tsx index 5638114c771..b22344bbec2 100644 --- a/apps/studio/components/interfaces/Database/Hooks/HTTPHeaders.tsx +++ b/apps/studio/components/interfaces/Database/Hooks/HTTPHeaders.tsx @@ -11,7 +11,7 @@ import { FormSectionContent, FormSectionLabel, } from '@/components/ui/Forms/FormSection' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { uuidv4 } from '@/lib/helpers' @@ -23,12 +23,14 @@ export const HTTPHeaders = ({ form }: HTTPHeadersProps) => { const { ref } = useParams() const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*') - const { data: apiKeys } = useAPIKeysQuery( - { projectRef: ref, reveal: true }, + const { data: apiKeyData } = useAPIKeys( + { + projectRef: ref, + reveal: true, + }, { enabled: canReadAPIKeys } ) - - const { serviceKey, secretKey } = getKeys(apiKeys) + const { serviceKey, secretKey } = apiKeyData ?? {} const apiKey = secretKey?.api_key ?? serviceKey?.api_key ?? '[YOUR API KEY]' const functionType = useWatch({ control: form.control, name: 'function_type' }) diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationPanelFields.tsx b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationPanelFields.tsx index 3c4bf58612a..55e5f478d8c 100644 --- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationPanelFields.tsx +++ b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationPanelFields.tsx @@ -24,7 +24,7 @@ import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import { CREATE_NEW_KEY, CREATE_NEW_NAMESPACE } from './DestinationForm.constants' import type { DestinationPanelSchemaType } from './DestinationForm.schema' import { InlineLink } from '@/components/ui/InlineLink' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { useAnalyticsBucketsQuery } from '@/data/storage/analytics-buckets-query' import { useIcebergNamespacesQuery } from '@/data/storage/iceberg-namespaces-query' import { useStorageCredentialsQuery } from '@/data/storage/s3-access-key-query' @@ -370,11 +370,11 @@ export const AnalyticsBucketFields = ({ const { ref: projectRef } = useParams() const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*') - const { data: apiKeys } = useAPIKeysQuery( + const { data: apiKeysData } = useAPIKeys( { projectRef, reveal: true }, { enabled: canReadAPIKeys } ) - const { serviceKey } = getKeys(apiKeys) + const { serviceKey } = apiKeysData ?? {} const serviceApiKey = serviceKey?.api_key ?? '' const { diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/index.tsx b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/index.tsx index 7d2c9d476e7..23b74ff3d7a 100644 --- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/index.tsx +++ b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/index.tsx @@ -31,7 +31,7 @@ import { PublicationSelection } from './PublicationSelection' import { ReplicationDisclaimerDialog } from './ReplicationDisclaimerDialog' import { ValidationFailuresSection } from './ValidationFailuresSection' import { CreateAnalyticsBucketSheet } from '@/components/interfaces/Storage/AnalyticsBuckets/CreateAnalyticsBucketSheet' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query' import { BatchConfig, @@ -149,11 +149,12 @@ export const DestinationForm = ({ pipelineId: existingDestination?.pipelineId, }) - const { data: apiKeys } = useAPIKeysQuery( + const { data: apiKeysData } = useAPIKeys( { projectRef, reveal: true }, { enabled: canReadAPIKeys } ) - const { serviceKey } = getKeys(apiKeys) + const { serviceKey } = apiKeysData ?? {} + const catalogToken = serviceKey?.api_key ?? '' const { data: projectSettings } = useProjectSettingsV2Query({ projectRef }) diff --git a/apps/studio/components/interfaces/Docs/Authentication.tsx b/apps/studio/components/interfaces/Docs/Authentication.tsx index d38f2440fe8..d0937e1c7e3 100644 --- a/apps/studio/components/interfaces/Docs/Authentication.tsx +++ b/apps/studio/components/interfaces/Docs/Authentication.tsx @@ -5,7 +5,7 @@ import CodeSnippet from './CodeSnippet' import { DocSection } from './DocSection' import Snippets from './Snippets' import { InlineLink } from '@/components/ui/InlineLink' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' @@ -17,10 +17,11 @@ interface AuthenticationProps { const Authentication = ({ selectedLang, showApiKey }: AuthenticationProps) => { const { ref: projectRef } = useParams() const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*') - const { data: apiKeys } = useAPIKeysQuery({ projectRef }, { enabled: canReadAPIKeys }) + const { data: apiKeyData } = useAPIKeys({ projectRef }, { enabled: canReadAPIKeys }) + const { anonKey, serviceKey } = apiKeyData ?? {} + const { data: settings } = useProjectSettingsV2Query({ projectRef }) - const { anonKey, serviceKey } = getKeys(apiKeys) const protocol = settings?.app_config?.protocol ?? 'https' const hostEndpoint = settings?.app_config?.endpoint const endpoint = `${protocol}://${hostEndpoint ?? ''}` diff --git a/apps/studio/components/interfaces/Functions/EdgeFunctionDetails/EdgeFunctionDetails.tsx b/apps/studio/components/interfaces/Functions/EdgeFunctionDetails/EdgeFunctionDetails.tsx index a0feafae502..1d584d547fb 100644 --- a/apps/studio/components/interfaces/Functions/EdgeFunctionDetails/EdgeFunctionDetails.tsx +++ b/apps/studio/components/interfaces/Functions/EdgeFunctionDetails/EdgeFunctionDetails.tsx @@ -42,7 +42,7 @@ import z from 'zod' import CommandRender from '../CommandRender' import { INVOCATION_TABS } from './EdgeFunctionDetails.constants' import { generateCLICommands } from './EdgeFunctionDetails.utils' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { useProjectApiUrl } from '@/data/config/project-endpoint-query' import { useEdgeFunctionQuery } from '@/data/edge-functions/edge-function-query' import { useEdgeFunctionDeleteMutation } from '@/data/edge-functions/edge-functions-delete-mutation' @@ -79,7 +79,8 @@ export const EdgeFunctionDetails = () => { const canUpdateEdgeFunction = IS_PLATFORM && canUpdateEdgeFunctionPermission const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*') - const { data: apiKeys } = useAPIKeysQuery({ projectRef }, { enabled: canReadAPIKeys }) + const { data: apiKeyData } = useAPIKeys({ projectRef }, { enabled: canReadAPIKeys }) + const { anonKey, publishableKey } = apiKeyData ?? {} const { data: selectedFunction } = useEdgeFunctionQuery({ projectRef, slug: functionSlug }) @@ -99,7 +100,6 @@ export const EdgeFunctionDetails = () => { defaultValues: { name: '', verify_jwt: false }, }) - const { anonKey, publishableKey } = getKeys(apiKeys) const apiKey = publishableKey?.api_key ?? anonKey?.api_key ?? '[YOUR ANON KEY]' const { managementCommands } = generateCLICommands({ diff --git a/apps/studio/components/interfaces/Functions/EdgeFunctionDetails/EdgeFunctionTesterSheet.tsx b/apps/studio/components/interfaces/Functions/EdgeFunctionDetails/EdgeFunctionTesterSheet.tsx index af30abc98aa..ac14a0b89d6 100644 --- a/apps/studio/components/interfaces/Functions/EdgeFunctionDetails/EdgeFunctionTesterSheet.tsx +++ b/apps/studio/components/interfaces/Functions/EdgeFunctionDetails/EdgeFunctionTesterSheet.tsx @@ -39,7 +39,7 @@ import { HTTP_METHODS } from './EdgeFunctionDetails.constants' import { ErrorWithStatus, ResponseData } from './EdgeFunctionDetails.types' import { RoleImpersonationPopover } from '@/components/interfaces/RoleImpersonationSelector/RoleImpersonationPopover' import { ShortcutTooltip } from '@/components/ui/ShortcutTooltip' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { useSessionAccessTokenQuery } from '@/data/auth/session-access-token-query' import { useProjectPostgrestConfigQuery } from '@/data/config/project-postgrest-config-query' import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query' @@ -102,11 +102,11 @@ const EdgeFunctionTesterSheetContent = ({ visible, onClose }: EdgeFunctionTester const [error, setError] = useState(null) const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*') - const { data: apiKeys } = useAPIKeysQuery({ projectRef }, { enabled: canReadAPIKeys }) + const { data: apiKeysData } = useAPIKeys({ projectRef }, { enabled: canReadAPIKeys }) + const { serviceKey } = apiKeysData ?? {} const { data: config } = useProjectPostgrestConfigQuery({ projectRef }) const { data: settings } = useProjectSettingsV2Query({ projectRef }) const { data: accessToken } = useSessionAccessTokenQuery({ enabled: IS_PLATFORM }) - const { serviceKey } = getKeys(apiKeys) const track = useTrack() const { mutate: testEdgeFunction, isPending } = useEdgeFunctionTestMutation({ diff --git a/apps/studio/components/interfaces/Functions/TerminalInstructions.tsx b/apps/studio/components/interfaces/Functions/TerminalInstructions.tsx index fe8e76381cc..9185e6518f4 100644 --- a/apps/studio/components/interfaces/Functions/TerminalInstructions.tsx +++ b/apps/studio/components/interfaces/Functions/TerminalInstructions.tsx @@ -9,7 +9,7 @@ import type { Commands } from './Functions.types' import CommandRender from '@/components/interfaces/Functions/CommandRender' import { DocsButton } from '@/components/ui/DocsButton' import { useAccessTokensQuery } from '@/data/access-tokens/access-tokens-query' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { useProjectApiUrl } from '@/data/config/project-endpoint-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { DOCS_URL } from '@/lib/constants' @@ -29,12 +29,12 @@ export const TerminalInstructions = forwardRef< const { data: tokens } = useAccessTokensQuery() const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*') - const { data: apiKeys } = useAPIKeysQuery({ projectRef }, { enabled: canReadAPIKeys }) + const { data: apiKeyData } = useAPIKeys({ projectRef }, { enabled: canReadAPIKeys }) + const { anonKey, publishableKey } = apiKeyData ?? {} const { data: endpoint } = useProjectApiUrl({ projectRef }) const functionsEndpoint = `${endpoint}/functions/v1` - const { anonKey, publishableKey } = getKeys(apiKeys) const apiKey = publishableKey?.api_key ?? anonKey?.api_key ?? '[YOUR ANON KEY]' // get the .co or .net TLD from the restUrl diff --git a/apps/studio/components/interfaces/Home/NewProjectPanel/APIKeys.tsx b/apps/studio/components/interfaces/Home/NewProjectPanel/APIKeys.tsx index 237dc813e83..a023a338390 100644 --- a/apps/studio/components/interfaces/Home/NewProjectPanel/APIKeys.tsx +++ b/apps/studio/components/interfaces/Home/NewProjectPanel/APIKeys.tsx @@ -11,7 +11,7 @@ import { ConnectionIcon } from '@/components/interfaces/Connect/ConnectionIcon' import { ConnectButton } from '@/components/interfaces/ConnectButton/ConnectButton' import { AlertError } from '@/components/ui/AlertError' import { InlineLink } from '@/components/ui/InlineLink' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { useLegacyAPIKeysStatusQuery } from '@/data/api-keys/legacy-api-keys-status-query' import { useJwtSecretUpdatingStatusQuery } from '@/data/config/jwt-secret-updating-status-query' import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query' @@ -32,12 +32,12 @@ export const APIKeys = () => { useLegacyAPIKeysStatusQuery({ projectRef }, { enabled: canReadAPIKeys }) const { - data: apiKeys, + data: apiKeysData, error: errorAPIKeys, isError: isErrorAPIKeys, isPending: isLoadingAPIKeys, - } = useAPIKeysQuery({ projectRef }, { enabled: canReadAPIKeys }) - const { anonKey, serviceKey, publishableKey, secretKey } = getKeys(apiKeys) + } = useAPIKeys({ projectRef }, { enabled: canReadAPIKeys }) + const { anonKey, serviceKey, publishableKey, secretKey } = apiKeysData ?? {} const hasNewAPIKeys = !!publishableKey && !!secretKey const isLegacyKeysEnabled = legacyAPIKeysStatusData?.enabled ?? false diff --git a/apps/studio/components/interfaces/Integrations/CronJobs/HttpHeaderFieldsSection.tsx b/apps/studio/components/interfaces/Integrations/CronJobs/HttpHeaderFieldsSection.tsx index c8ca4054481..5212f876416 100644 --- a/apps/studio/components/interfaces/Integrations/CronJobs/HttpHeaderFieldsSection.tsx +++ b/apps/studio/components/interfaces/Integrations/CronJobs/HttpHeaderFieldsSection.tsx @@ -6,7 +6,7 @@ import { KeyValueFieldArray } from 'ui-patterns/form/KeyValueFieldArray/KeyValue import { CreateCronJobForm } from './CreateCronJobSheet/CreateCronJobSheet.constants' import { buildEdgeFunctionHeaderAddActions } from '@/components/interfaces/Functions/httpHeaderAddActions' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' interface HTTPHeaderFieldsSectionProps { @@ -18,12 +18,12 @@ export const HTTPHeaderFieldsSection = ({ variant }: HTTPHeaderFieldsSectionProp const { ref } = useParams() const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*') - const { data: apiKeys } = useAPIKeysQuery( + const { data: apiKeysData } = useAPIKeys( { projectRef: ref, reveal: true }, { enabled: canReadAPIKeys } ) + const { serviceKey, secretKey } = apiKeysData ?? {} - const { serviceKey, secretKey } = getKeys(apiKeys) const apiKey = secretKey?.api_key ?? serviceKey?.api_key ?? '[YOUR API KEY]' const addActions = variant === 'edge_function' diff --git a/apps/studio/components/interfaces/ProjectAPIDocs/Content/Introduction.tsx b/apps/studio/components/interfaces/ProjectAPIDocs/Content/Introduction.tsx index 4594cee9971..a29d0fdfe3e 100644 --- a/apps/studio/components/interfaces/ProjectAPIDocs/Content/Introduction.tsx +++ b/apps/studio/components/interfaces/ProjectAPIDocs/Content/Introduction.tsx @@ -9,7 +9,7 @@ import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import ContentSnippet from '../ContentSnippet' import { DOCS_CONTENT } from '../ProjectAPIDocs.constants' import type { ContentProps } from './Content.types' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { useTrack } from '@/lib/telemetry/track' @@ -17,8 +17,10 @@ import { useTrack } from '@/lib/telemetry/track' export const Introduction = ({ showKeys, language, apikey, endpoint }: ContentProps) => { const { ref } = useParams() const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*') - const { data: apiKeys } = useAPIKeysQuery({ projectRef: ref }, { enabled: canReadAPIKeys }) + const { data: apiKeysData } = useAPIKeys({ projectRef: ref }, { enabled: canReadAPIKeys }) useProjectSettingsV2Query({ projectRef: ref }) + const { anonKey, serviceKey } = apiKeysData ?? {} + const track = useTrack() const [copied, setCopied] = useState<'anon' | 'service'>() @@ -27,7 +29,6 @@ export const Introduction = ({ showKeys, language, apikey, endpoint }: ContentPr if (copied !== undefined) setTimeout(() => setCopied(undefined), 2000) }, [copied]) - const { anonKey, serviceKey } = getKeys(apiKeys) const anonApiKey = anonKey?.api_key const serviceApiKey = serviceKey?.api_key ?? 'SUPABASE_CLIENT_SERVICE_KEY' diff --git a/apps/studio/components/interfaces/ProjectAPIDocs/ProjectAPIDocs.tsx b/apps/studio/components/interfaces/ProjectAPIDocs/ProjectAPIDocs.tsx index 2e86d2b6937..b5236ff29f4 100644 --- a/apps/studio/components/interfaces/ProjectAPIDocs/ProjectAPIDocs.tsx +++ b/apps/studio/components/interfaces/ProjectAPIDocs/ProjectAPIDocs.tsx @@ -17,7 +17,7 @@ import { UserManagement } from './Content/UserManagement' import { FirstLevelNav } from './FirstLevelNav' import LanguageSelector from './LanguageSelector' import { SecondLevelNav } from './SecondLevelNav' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { useProjectApiUrl } from '@/data/config/project-endpoint-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { useAppStateSnapshot } from '@/state/app-state' @@ -45,17 +45,17 @@ export const ProjectAPIDocs = () => { const language = snap.docsLanguage const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*') - const { data: apiKeys } = useAPIKeysQuery( + const { data: apiKeysData } = useAPIKeys( { projectRef: ref }, { enabled: snap.showProjectApiDocs && canReadAPIKeys } ) + const { anonKey } = apiKeysData ?? {} const { data: endpoint } = useProjectApiUrl( { projectRef: ref }, { enabled: snap.showProjectApiDocs } ) - const { anonKey } = getKeys(apiKeys) const apikey = showKeys ? (anonKey?.api_key ?? 'SUPABASE_CLIENT_ANON_KEY') : 'SUPABASE_CLIENT_ANON_KEY' diff --git a/apps/studio/components/interfaces/ProjectHome/ProjectConnectionPopover.tsx b/apps/studio/components/interfaces/ProjectHome/ProjectConnectionPopover.tsx index b126619052b..c9911399469 100644 --- a/apps/studio/components/interfaces/ProjectHome/ProjectConnectionPopover.tsx +++ b/apps/studio/components/interfaces/ProjectHome/ProjectConnectionPopover.tsx @@ -15,7 +15,7 @@ import { import { ShimmeringLoader } from 'ui-patterns' import { getConnectionStrings } from '@/components/interfaces/Connect/DatabaseSettings.utils' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { useProjectApiUrl } from '@/data/config/project-endpoint-query' import { useReadReplicasQuery } from '@/data/read-replicas/replicas-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' @@ -47,11 +47,11 @@ export const ProjectConnectionPopover = ({ projectRef }: ProjectConnectionPopove const { data: projectUrl, isPending: isLoadingApiUrl } = useProjectApiUrl({ projectRef }) - const { data: apiKeys, isLoading: isLoadingKeys } = useAPIKeysQuery( + const { data, isLoading: isLoadingKeys } = useAPIKeys( { projectRef }, { enabled: open && canReadAPIKeys } ) - const { publishableKey } = canReadAPIKeys ? getKeys(apiKeys) : { publishableKey: null } + const { publishableKey } = data ?? {} const { data: databases, isLoading: isLoadingDatabases } = useReadReplicasQuery( { projectRef }, diff --git a/apps/studio/components/interfaces/Realtime/Inspector/RealtimeTokensPopover.tsx b/apps/studio/components/interfaces/Realtime/Inspector/RealtimeTokensPopover.tsx index e0b304f71f6..537edafb374 100644 --- a/apps/studio/components/interfaces/Realtime/Inspector/RealtimeTokensPopover.tsx +++ b/apps/studio/components/interfaces/Realtime/Inspector/RealtimeTokensPopover.tsx @@ -4,7 +4,7 @@ import { toast } from 'sonner' import { RealtimeConfig } from './useRealtimeMessages' import { RoleImpersonationPopover } from '@/components/interfaces/RoleImpersonationSelector/RoleImpersonationPopover' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { getTemporaryAPIKey } from '@/data/api-keys/temp-api-keys-query' import { useProjectPostgrestConfigQuery } from '@/data/config/project-postgrest-config-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' @@ -22,15 +22,13 @@ export const RealtimeTokensPopover = ({ config, onChangeConfig }: RealtimeTokens const snap = useRoleImpersonationStateSnapshot() const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*') - const { data: apiKeys } = useAPIKeysQuery( + const { data: apiKeysData } = useAPIKeys( { projectRef: config.projectRef, reveal: true, }, { enabled: canReadAPIKeys } ) - const { anonKey, publishableKey } = getKeys(apiKeys) - const { data: postgrestConfig } = useProjectPostgrestConfigQuery( { projectRef: config.projectRef }, { enabled: IS_PLATFORM } @@ -55,6 +53,7 @@ export const RealtimeTokensPopover = ({ config, onChangeConfig }: RealtimeTokens }, [snap.role]) useEffect(() => { + const { anonKey, publishableKey } = apiKeysData ?? {} const triggerUpdateTokenBearer = async () => { let token: string | undefined let bearer: string | null = null @@ -84,7 +83,7 @@ export const RealtimeTokensPopover = ({ config, onChangeConfig }: RealtimeTokens triggerUpdateTokenBearer() // eslint-disable-next-line react-hooks/exhaustive-deps - }, [snap.role, anonKey]) + }, [snap.role, apiKeysData]) return } diff --git a/apps/studio/components/interfaces/Storage/VectorBuckets/VectorBucketDetails/VectorBucketTableExamplesSheet.tsx b/apps/studio/components/interfaces/Storage/VectorBuckets/VectorBucketDetails/VectorBucketTableExamplesSheet.tsx index 7a96ed77d3b..50189738df3 100644 --- a/apps/studio/components/interfaces/Storage/VectorBuckets/VectorBucketDetails/VectorBucketTableExamplesSheet.tsx +++ b/apps/studio/components/interfaces/Storage/VectorBuckets/VectorBucketDetails/VectorBucketTableExamplesSheet.tsx @@ -28,7 +28,7 @@ import { CodeBlock } from 'ui-patterns/CodeBlock' import { useS3VectorsWrapperExtension } from '../useS3VectorsWrapper' import { useS3VectorsWrapperInstance } from '../useS3VectorsWrapperInstance' import { DocsButton } from '@/components/ui/DocsButton' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { VectorBucketIndex } from '@/data/storage/vector-buckets-indexes-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { DOCS_URL } from '@/lib/constants' @@ -143,8 +143,8 @@ function VectorBucketIndexExamples({ PermissionAction.READ, 'service_api_keys' ) - const { data: apiKeys } = useAPIKeysQuery({ projectRef }, { enabled: canReadAPIKeys }) - const { secretKey } = canReadAPIKeys ? getKeys(apiKeys) : { secretKey: null } + const { data: apiKeysData } = useAPIKeys({ projectRef }, { enabled: canReadAPIKeys }) + const { secretKey } = apiKeysData ?? {} const { data: wrapperInstance } = useS3VectorsWrapperInstance({ bucketId }) const foreignTable = wrapperInstance?.tables?.find((x) => x.name === indexName) @@ -177,7 +177,7 @@ values const jsCode = `import { createClient } from '@supabase/supabase-js' -// Adding vector data requires a secret or service role key +// Adding vector data requires a secret or service role key // This code SHOULD NOT be run on the client side as you will be vulnerable to a data leak const client = createClient( process.env.SUPABASE_URL, diff --git a/apps/studio/data/api-keys/api-keys-query.ts b/apps/studio/data/api-keys/api-keys-query.ts index be0f873b947..a9f87625e38 100644 --- a/apps/studio/data/api-keys/api-keys-query.ts +++ b/apps/studio/data/api-keys/api-keys-query.ts @@ -1,4 +1,5 @@ import { useQuery } from '@tanstack/react-query' +import { useCallback } from 'react' import { apiKeysKeys } from './keys' import { get, handleError } from '@/data/fetchers' @@ -78,7 +79,18 @@ export const useAPIKeysQuery = ( }) } +const EmptyKey = { + anonKey: undefined, + serviceKey: undefined, + publishableKey: undefined, + secretKey: undefined, + allSecretKeys: [], +} + export const getKeys = (apiKeys: APIKey[] = []) => { + if (!Array.isArray(apiKeys)) { + return EmptyKey + } const anonKey = apiKeys.find((x) => x.name === 'anon') const serviceKey = apiKeys.find((x) => x.name === 'service_role') @@ -90,3 +102,21 @@ export const getKeys = (apiKeys: APIKey[] = []) => { return { anonKey, serviceKey, publishableKey, secretKey, allSecretKeys } } + +const PlaceholderData: APIKeysData = [] + +export const useAPIKeys = ( + variables: APIKeysVariables, + options: UseCustomQueryOptions = {} +) => { + const select = useCallback( + (data: APIKeysData) => getKeys(options.enabled ? data : []), + [options.enabled] + ) + + return useAPIKeysQuery(variables, { + ...options, + placeholderData: PlaceholderData, + select, + }) +} diff --git a/apps/studio/data/storage/iceberg-wrapper-create-mutation.ts b/apps/studio/data/storage/iceberg-wrapper-create-mutation.ts index 3876f34ff2a..c98ad6d0217 100644 --- a/apps/studio/data/storage/iceberg-wrapper-create-mutation.ts +++ b/apps/studio/data/storage/iceberg-wrapper-create-mutation.ts @@ -10,7 +10,7 @@ import { getCatalogURI, getConnectionURL, } from '@/components/interfaces/Storage/StorageSettings/StorageSettings.utils' -import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' +import { useAPIKeys } from '@/data/api-keys/api-keys-query' import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query' import { FDWCreateVariables, useFDWCreateMutation } from '@/data/fdw/fdw-create-mutation' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' @@ -20,12 +20,11 @@ export const useIcebergWrapperCreateMutation = () => { const { data: project } = useSelectedProjectQuery() const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*') - const { data: apiKeys } = useAPIKeysQuery( + const { data: apiKeysData } = useAPIKeys( { projectRef: project?.ref, reveal: true }, { enabled: canReadAPIKeys } ) - const { secretKey, serviceKey } = getKeys(apiKeys) - + const { secretKey, serviceKey } = apiKeysData ?? {} const { data: settings } = useProjectSettingsV2Query({ projectRef: project?.ref }) const protocol = settings?.app_config?.protocol ?? 'https' const endpoint = settings?.app_config?.storage_endpoint || settings?.app_config?.endpoint From 122171aecbd82fa77d52ee65542912393350d051 Mon Sep 17 00:00:00 2001 From: Ali Waseem Date: Tue, 9 Jun 2026 07:55:28 -0600 Subject: [PATCH 055/134] fix: correct usage page URL from /organization to /org (#46777) The usage page link in the UpcomingInvoice billing breakdown used the incorrect path, resulting in a 404. Corrected to to match the rest of the app. ## Summary by CodeRabbit * **Bug Fixes** * Corrected the usage page link shown in the billing breakdown tooltip for non-compute items so it now points to the proper /org/... URL, ensuring users are taken to the correct usage page from billing documentation. --- .../BillingSettings/BillingBreakdown/UpcomingInvoice.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/studio/components/interfaces/Organization/BillingSettings/BillingBreakdown/UpcomingInvoice.tsx b/apps/studio/components/interfaces/Organization/BillingSettings/BillingBreakdown/UpcomingInvoice.tsx index 9784ed2574c..8cd47c2c690 100644 --- a/apps/studio/components/interfaces/Organization/BillingSettings/BillingBreakdown/UpcomingInvoice.tsx +++ b/apps/studio/components/interfaces/Organization/BillingSettings/BillingBreakdown/UpcomingInvoice.tsx @@ -277,9 +277,7 @@ export const UpcomingInvoice = ({ slug }: UpcomingInvoiceProps) => { docs {' '} on how billing for {item.description} works and{' '} - - usage page - {' '} + usage page{' '} for a detailed breakdown.

)} From 00afaeac7354913d5153e288511d289ec9a34f76 Mon Sep 17 00:00:00 2001 From: Danny White <3104761+dnywh@users.noreply.github.com> Date: Tue, 9 Jun 2026 08:07:17 -0600 Subject: [PATCH 056/134] feat(studio): Issuer field in SSO form (#46187) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > [!CAUTION] > This new SSO field is UI-only until `oidc_issuer` is added to the `config` object. ## What kind of change does this PR introduce? Feature ## What is the current behavior? The SAML SSO provider config form has no way to supply an OIDC Issuer URL, which is required for enterprise-managed MCP authentication. ## What is the new behavior? - Adds an **OIDC Issuer URL** field to the SAML SSO provider config form (`/org/_/sso`) inside an "Advanced settings" collapsible. - Minor UI touch-ups to that SSO form. | After | | --- | | 94962 | The `oidcIssuer` field is UI-only right now; it renders but does not write. Before merging: 1. Add `oidc_issuer` to the SSO config API type (removes the `as any` cast in `SSOConfig.tsx:219`) 2. Add `oidc_issuer: values.oidcIssuer || undefined` to the `onSubmit` payload at `SSOConfig.tsx:183` 3. Wire the backend endpoint to persist and return the field ## Summary by CodeRabbit * **New Features** * SSO settings now include an "Advanced settings" collapsible with an OIDC issuer field. * **UX / Bug Fixes** * Small UI/description refinements in SSO forms and attribute-mapping layouts. [![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46187?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) --------- Co-authored-by: Claude Sonnet 4.6 Co-authored-by: Cemal Kilic Co-authored-by: Cemal Kılıç --- .../Organization/SSO/AttributeMapping.tsx | 19 ++- .../SSO/JoinOrganizationOnSignup.tsx | 2 +- .../Organization/SSO/SSOAdvancedSettings.tsx | 29 ++++ .../interfaces/Organization/SSO/SSOConfig.tsx | 31 +++-- .../Organization/SSO/SSOMetadata.tsx | 2 +- packages/api-types/types/api.d.ts | 75 ++++++++++- packages/api-types/types/platform.d.ts | 124 +++++++++++++++++- 7 files changed, 254 insertions(+), 28 deletions(-) create mode 100644 apps/studio/components/interfaces/Organization/SSO/SSOAdvancedSettings.tsx diff --git a/apps/studio/components/interfaces/Organization/SSO/AttributeMapping.tsx b/apps/studio/components/interfaces/Organization/SSO/AttributeMapping.tsx index 570b7f2b66a..96d8525d08a 100644 --- a/apps/studio/components/interfaces/Organization/SSO/AttributeMapping.tsx +++ b/apps/studio/components/interfaces/Organization/SSO/AttributeMapping.tsx @@ -108,17 +108,14 @@ export const AttributeMapping = ({ label="Attribute mapping" layout="flex-row-reverse" description={ -
-

Map SSO attributes to user fields

-
-

Presets for supported identity providers:

-
- {PROVIDER_PRESETS.map((preset) => ( - - ))} -
+
+

Map SSO attributes to user fields. Presets for supported identity providers:

+
+ {PROVIDER_PRESETS.map((preset) => ( + + ))}
} diff --git a/apps/studio/components/interfaces/Organization/SSO/JoinOrganizationOnSignup.tsx b/apps/studio/components/interfaces/Organization/SSO/JoinOrganizationOnSignup.tsx index a862eba674d..bf794b9297d 100644 --- a/apps/studio/components/interfaces/Organization/SSO/JoinOrganizationOnSignup.tsx +++ b/apps/studio/components/interfaces/Organization/SSO/JoinOrganizationOnSignup.tsx @@ -30,7 +30,7 @@ export const JoinOrganizationOnSignup = ({ diff --git a/apps/studio/components/interfaces/Organization/SSO/SSOAdvancedSettings.tsx b/apps/studio/components/interfaces/Organization/SSO/SSOAdvancedSettings.tsx new file mode 100644 index 00000000000..5faea44747f --- /dev/null +++ b/apps/studio/components/interfaces/Organization/SSO/SSOAdvancedSettings.tsx @@ -0,0 +1,29 @@ +import type { UseFormReturn } from 'react-hook-form' +import { FormControl, FormField, Input } from 'ui' +import { CollapsibleCardSection } from 'ui-patterns/CollapsibleCardSection' +import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' + +import type { SSOConfigFormSchema } from './SSOConfig' + +export const SSOAdvancedSettings = ({ form }: { form: UseFormReturn }) => ( + + ( + + + + + + )} + /> + +) diff --git a/apps/studio/components/interfaces/Organization/SSO/SSOConfig.tsx b/apps/studio/components/interfaces/Organization/SSO/SSOConfig.tsx index 152e46b3e03..e9e697ba9a2 100644 --- a/apps/studio/components/interfaces/Organization/SSO/SSOConfig.tsx +++ b/apps/studio/components/interfaces/Organization/SSO/SSOConfig.tsx @@ -1,4 +1,5 @@ import { zodResolver } from '@hookform/resolvers/zod' +import { useFlag } from 'common' import { Trash } from 'lucide-react' import { useEffect, useEffectEvent, useState } from 'react' import { SubmitHandler, useForm } from 'react-hook-form' @@ -11,6 +12,7 @@ import z from 'zod' import { AttributeMapping } from './AttributeMapping' import { JoinOrganizationOnSignup } from './JoinOrganizationOnSignup' +import { SSOAdvancedSettings } from './SSOAdvancedSettings' import { SSODomains } from './SSODomains' import { SSOMetadata } from './SSOMetadata' import { ScaffoldContainer, ScaffoldSection } from '@/components/layouts/Scaffold' @@ -44,6 +46,7 @@ const FormSchema = z lastNameMapping: z.array(z.object({ value: z.string().trim() })), joinOrgOnSignup: z.boolean(), roleOnJoin: z.string().optional(), + idjagIssuerUrl: z.string().trim().optional(), }) .superRefine((data, ctx) => { if (!data.enableSpInitiated) return @@ -91,6 +94,7 @@ const defaultValues = { lastNameMapping: [{ value: '' }], joinOrgOnSignup: false, roleOnJoin: 'Developer', + idjagIssuerUrl: '', } export const SSOConfig = () => { @@ -99,6 +103,13 @@ export const SSOConfig = () => { const { data: organization } = useSelectedOrganizationQuery() const { hasAccess: hasAccessToSso, isLoading: isLoadingEntitlement } = useCheckEntitlements('auth.platform.sso') + const enterpriseMcpAuthOrgs = useFlag('enableEnterpriseMcpAuth') + const showIdjagSettings = + typeof enterpriseMcpAuthOrgs === 'string' && + enterpriseMcpAuthOrgs + .split(',') + .map((s) => s.trim()) + .includes(organization?.slug ?? '') const { data: ssoConfig, @@ -171,6 +182,7 @@ export const SSOConfig = () => { user_name_mapping: values.userNameMapping.map((item) => item.value).filter(Boolean), join_org_on_signup_enabled: values.joinOrgOnSignup, join_org_on_signup_role: roleOnJoin, + idjag_issuer_url: values.idjagIssuerUrl || undefined, }, } @@ -207,6 +219,7 @@ export const SSOConfig = () => { ssoConfig.last_name_mapping?.map((lastName) => ({ value: lastName })) || [], joinOrgOnSignup: ssoConfig.join_org_on_signup_enabled, roleOnJoin: ssoConfig.join_org_on_signup_role, + idjagIssuerUrl: ssoConfig.idjag_issuer_url ?? '', }) } }) @@ -259,27 +272,23 @@ export const SSOConfig = () => { name="enabled" render={({ field }) => ( - Enable and configure SSO for your organization. Learn more about SSO{' '} + Enable and configure SSO for your organization.{' '} - here + Learn more . } > - + )} @@ -360,6 +369,12 @@ export const SSOConfig = () => { + + {showIdjagSettings && ( + + + + )} )} diff --git a/apps/studio/components/interfaces/Organization/SSO/SSOMetadata.tsx b/apps/studio/components/interfaces/Organization/SSO/SSOMetadata.tsx index 1138daeebae..bd270e2bb51 100644 --- a/apps/studio/components/interfaces/Organization/SSO/SSOMetadata.tsx +++ b/apps/studio/components/interfaces/Organization/SSO/SSOMetadata.tsx @@ -61,7 +61,7 @@ export const SSOMetadata = ({
diff --git a/packages/api-types/types/api.d.ts b/packages/api-types/types/api.d.ts index 362b857dd5b..1c01c92840a 100644 --- a/packages/api-types/types/api.d.ts +++ b/packages/api-types/types/api.d.ts @@ -195,7 +195,10 @@ export interface paths { } get?: never put?: never - /** [Beta] Exchange auth code for user's access and refresh token */ + /** + * [Beta] Exchange auth code for user's access and refresh token + * @description Supports `authorization_code`, `refresh_token`, and `urn:ietf:params:oauth:grant-type:jwt-bearer` grant types. The `jwt-bearer` grant type (IDJAG — identity-directed JWT assertion) is in beta and available on Team and Enterprise plans only. + */ post: operations['v1-exchange-oauth-token'] delete?: never options?: never @@ -3485,13 +3488,18 @@ export interface components { * "scope": "projects:read projects:write" * } */ OAuthTokenBody: { + /** @description IDJAG assertion JWT for grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer. Beta - available on Team and Enterprise plans only. */ + assertion?: string /** Format: uuid */ client_id?: string client_secret?: string code?: string code_verifier?: string /** @enum {string} */ - grant_type?: 'authorization_code' | 'refresh_token' + grant_type?: + | 'authorization_code' + | 'refresh_token' + | 'urn:ietf:params:oauth:grant-type:jwt-bearer' redirect_uri?: string refresh_token?: string /** @@ -3504,7 +3512,8 @@ export interface components { OAuthTokenResponse: { access_token: string expires_in: number - refresh_token: string + /** @description The `urn:ietf:params:oauth:grant-type:jwt-bearer` grant type issues access tokens only, no refresh token is returned and the token cannot be revoked via `/v1/oauth/revoke`. */ + refresh_token?: string /** @enum {string} */ token_type: 'Bearer' } @@ -3643,8 +3652,21 @@ export interface components { PostgresConfigResponse: { /** @description Default unit: s */ checkpoint_timeout?: string + 'cron.log_statement'?: boolean effective_cache_size?: string hot_standby_feedback?: boolean + /** @description Default unit: ms */ + log_autovacuum_min_duration?: string + log_checkpoints?: boolean + log_connections?: boolean + log_disconnections?: boolean + log_duration?: boolean + log_lock_waits?: boolean + log_recovery_conflict_waits?: boolean + log_replication_commands?: boolean + /** @description Default unit: ms */ + log_startup_progress_interval?: string + log_temp_files?: string logical_decoding_work_mem?: string maintenance_work_mem?: string max_connections?: number @@ -4511,8 +4533,21 @@ export interface components { UpdatePostgresConfigBody: { /** @description Default unit: s */ checkpoint_timeout?: string + 'cron.log_statement'?: boolean effective_cache_size?: string hot_standby_feedback?: boolean + /** @description Default unit: ms */ + log_autovacuum_min_duration?: string + log_checkpoints?: boolean + log_connections?: boolean + log_disconnections?: boolean + log_duration?: boolean + log_lock_waits?: boolean + log_recovery_conflict_waits?: boolean + log_replication_commands?: boolean + /** @description Default unit: ms */ + log_startup_progress_interval?: string + log_temp_files?: string logical_decoding_work_mem?: string maintenance_work_mem?: string max_connections?: number @@ -5789,7 +5824,7 @@ export interface operations { } } responses: { - 201: { + 200: { headers: { [name: string]: unknown } @@ -9912,7 +9947,7 @@ export interface operations { } content?: never } - /** @description Feature requires a higher plan */ + /** @description This feature requires the Enterprise organization plan. */ 402: { headers: { [name: string]: unknown @@ -9987,7 +10022,7 @@ export interface operations { } content?: never } - /** @description Feature requires a higher plan */ + /** @description This feature requires the Enterprise organization plan. */ 402: { headers: { [name: string]: unknown @@ -12218,6 +12253,13 @@ export interface operations { } content?: never } + /** @description This feature requires the Pro, Team, or Enterprise organization plan. */ + 402: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Forbidden action */ 403: { headers: { @@ -13000,6 +13042,13 @@ export interface operations { 'application/json': components['schemas']['VanitySubdomainConfigResponse'] } } + /** @description This feature requires the Pro, Team, or Enterprise organization plan. */ + 400: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Unauthorized */ 401: { headers: { @@ -13102,6 +13151,13 @@ export interface operations { 'application/json': components['schemas']['ActivateVanitySubdomainResponse'] } } + /** @description This feature requires the Pro, Team, or Enterprise organization plan. */ + 400: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Unauthorized */ 401: { headers: { @@ -13156,6 +13212,13 @@ export interface operations { 'application/json': components['schemas']['SubdomainAvailabilityResponse'] } } + /** @description This feature requires the Pro, Team, or Enterprise organization plan. */ + 400: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Unauthorized */ 401: { headers: { diff --git a/packages/api-types/types/platform.d.ts b/packages/api-types/types/platform.d.ts index ba5359d3206..0b423d0f6ba 100644 --- a/packages/api-types/types/platform.d.ts +++ b/packages/api-types/types/platform.d.ts @@ -6197,6 +6197,8 @@ export interface components { email_mapping: string[] enabled: boolean first_name_mapping?: string[] + /** Format: uri */ + idjag_issuer_url?: string | null join_org_on_signup_enabled: boolean /** @enum {string} */ join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only' @@ -6212,6 +6214,8 @@ export interface components { email_mapping: string[] enabled: boolean first_name_mapping?: string[] + /** Format: uri */ + idjag_issuer_url?: string | null join_org_on_signup_enabled: boolean /** @enum {string} */ join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only' @@ -6227,6 +6231,8 @@ export interface components { email_mapping: string[] enabled: boolean first_name_mapping?: string[] + /** Format: uri */ + idjag_issuer_url?: string | null join_org_on_signup_enabled: boolean /** @enum {string} */ join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only' @@ -6242,6 +6248,8 @@ export interface components { email_mapping: string[] enabled: boolean first_name_mapping?: string[] + /** Format: uri */ + idjag_issuer_url?: string | null join_org_on_signup_enabled: boolean /** @enum {string} */ join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only' @@ -7077,6 +7085,8 @@ export interface components { email_mapping: string[] enabled: boolean first_name_mapping?: string[] + /** Format: uri */ + idjag_issuer_url?: string | null join_org_on_signup_enabled: boolean /** @enum {string} */ join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only' @@ -7092,6 +7102,8 @@ export interface components { email_mapping: string[] enabled: boolean first_name_mapping?: string[] + /** Format: uri */ + idjag_issuer_url?: string | null join_org_on_signup_enabled: boolean /** @enum {string} */ join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only' @@ -11766,6 +11778,8 @@ export interface components { email_mapping: string[] enabled: boolean first_name_mapping?: string[] + /** Format: uri */ + idjag_issuer_url?: string | null join_org_on_signup_enabled: boolean /** @enum {string} */ join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only' @@ -11781,6 +11795,8 @@ export interface components { email_mapping: string[] enabled: boolean first_name_mapping?: string[] + /** Format: uri */ + idjag_issuer_url?: string | null join_org_on_signup_enabled: boolean /** @enum {string} */ join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only' @@ -11796,6 +11812,8 @@ export interface components { email_mapping: string[] enabled: boolean first_name_mapping?: string[] + /** Format: uri */ + idjag_issuer_url?: string | null join_org_on_signup_enabled: boolean /** @enum {string} */ join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only' @@ -11811,6 +11829,8 @@ export interface components { email_mapping: string[] enabled: boolean first_name_mapping?: string[] + /** Format: uri */ + idjag_issuer_url?: string | null join_org_on_signup_enabled: boolean /** @enum {string} */ join_org_on_signup_role?: 'Administrator' | 'Developer' | 'Owner' | 'Read-only' @@ -13561,6 +13581,13 @@ export interface operations { } content?: never } + /** @description This feature requires the Pro, Team, or Enterprise organization plan. */ + 402: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Forbidden action */ 403: { headers: { @@ -14378,6 +14405,13 @@ export interface operations { } content?: never } + /** @description This feature requires the Team, or Enterprise organization plan. */ + 402: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Forbidden action */ 403: { headers: { @@ -14431,6 +14465,13 @@ export interface operations { } content?: never } + /** @description This feature requires the Team, or Enterprise organization plan. */ + 402: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Forbidden action */ 403: { headers: { @@ -15089,6 +15130,13 @@ export interface operations { } content?: never } + /** @description This feature requires the Team, or Enterprise organization plan. */ + 402: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Forbidden action */ 403: { headers: { @@ -17168,6 +17216,13 @@ export interface operations { 'application/json': components['schemas']['OrgDocumentUrlResponse'] } } + /** @description Only organizations on Team, Enterprise or Platform Plan can access our ISO 27001 certificate. */ + 400: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Unauthorized */ 401: { headers: { @@ -17211,6 +17266,13 @@ export interface operations { 'application/json': components['schemas']['OrgDocumentUrlResponse'] } } + /** @description Only organizations on Team, Enterprise or Platform Plan can access our SOC2 Type 2 report. */ + 400: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Unauthorized */ 401: { headers: { @@ -17254,6 +17316,13 @@ export interface operations { 'application/json': components['schemas']['OrgDocumentUrlResponse'] } } + /** @description Only organizations on Team, Enterprise or Platform Plan can access our standard security questionnaire. */ + 400: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Unauthorized */ 401: { headers: { @@ -17850,6 +17919,13 @@ export interface operations { } content?: never } + /** @description This feature requires the Pro, Team, or Enterprise organization plan. */ + 402: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Forbidden action */ 403: { headers: { @@ -18789,6 +18865,13 @@ export interface operations { } content?: never } + /** @description This feature requires the Team, or Enterprise organization plan. */ + 402: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Forbidden action */ 403: { headers: { @@ -21248,6 +21331,13 @@ export interface operations { } content?: never } + /** @description This feature requires the Pro, Team, or Enterprise organization plan. */ + 402: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Forbidden action */ 403: { headers: { @@ -23497,6 +23587,8 @@ export interface operations { | 'ram_usage_free' | 'ram_usage_cache_and_buffers' | 'ram_usage_swap' + | 'ram_commit_used' + | 'ram_commit_limit' | 'swap_usage' | 'client_connections_pgbouncer' | 'network_receive_bytes' @@ -23553,6 +23645,8 @@ export interface operations { | 'ram_usage_free' | 'ram_usage_cache_and_buffers' | 'ram_usage_swap' + | 'ram_commit_used' + | 'ram_commit_limit' | 'swap_usage' | 'client_connections_pgbouncer' | 'network_receive_bytes' @@ -24100,7 +24194,7 @@ export interface operations { } content?: never } - /** @description AWS PrivateLink is not available for the current billing plan. */ + /** @description Invalid request format */ 400: { headers: { [name: string]: unknown @@ -24114,6 +24208,13 @@ export interface operations { } content?: never } + /** @description This feature requires the Team, or Enterprise organization plan. */ + 402: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Forbidden action */ 403: { headers: { @@ -24223,6 +24324,13 @@ export interface operations { } content?: never } + /** @description This feature requires the Pro, Team, or Enterprise organization plan. */ + 402: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Forbidden action */ 403: { headers: { @@ -26285,6 +26393,13 @@ export interface operations { } content?: never } + /** @description This feature requires the Pro, Team, or Enterprise organization plan. */ + 402: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Forbidden action */ 403: { headers: { @@ -26677,6 +26792,13 @@ export interface operations { } content?: never } + /** @description This feature requires the Pro, Team, or Enterprise organization plan. */ + 402: { + headers: { + [name: string]: unknown + } + content?: never + } /** @description Forbidden action */ 403: { headers: { From 2c915ca9fba14de4292b68da48abb240ebe27276 Mon Sep 17 00:00:00 2001 From: Jordi Enric <37541088+jordienr@users.noreply.github.com> Date: Tue, 9 Jun 2026 16:23:26 +0200 Subject: [PATCH 057/134] fix(observability): align overview Connections count with details view DEBUG-75 (#46271) --- .../DatabaseInfrastructureSection.tsx | 6 +- ...atabaseInfrastructureSection.utils.test.ts | 151 ++++++++++-------- .../DatabaseInfrastructureSection.utils.ts | 24 +-- .../InstanceNode.tsx | 2 +- .../hooks/analytics/useComputeMetrics.ts | 2 +- 5 files changed, 100 insertions(+), 85 deletions(-) diff --git a/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.tsx b/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.tsx index 61f6dbfca12..9c92aac9781 100644 --- a/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.tsx +++ b/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.tsx @@ -169,8 +169,8 @@ export const DatabaseInfrastructureSection = ({ - - Connections + + Peak Connections @@ -178,7 +178,7 @@ export const DatabaseInfrastructureSection = ({
{errorMessage}
) : connections.max > 0 ? ( - {connections.current}/{connections.max} + {connections.peak}/{connections.max} ) : ( -- diff --git a/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.utils.test.ts b/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.utils.test.ts index de1bdbaf819..75e97896df7 100644 --- a/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.utils.test.ts +++ b/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.utils.test.ts @@ -192,103 +192,114 @@ describe('parseInfrastructureMetrics', () => { }) describe('parseConnectionsData', () => { + const buildResponse = ( + values: Array + ): InfraMonitoringMultiResponse => ({ + data: values.map((v, i) => ({ + period_start: `2026-05-22T00:0${i}:00.000Z`, + values: { pg_stat_database_num_backends: v as string | undefined }, + })), + series: { + pg_stat_database_num_backends: { + format: 'number', + total: 0, + totalAverage: 0, + yAxisLimit: 100, + }, + }, + }) + it('returns zeros when data is undefined', () => { - expect(parseConnectionsData(undefined, undefined)).toEqual({ current: 0, max: 0 }) + expect(parseConnectionsData(undefined, undefined)).toEqual({ peak: 0, max: 0 }) expect(parseConnectionsData(undefined, { maxConnections: 100 })).toEqual({ - current: 0, - max: 0, + peak: 0, + max: 100, }) }) - it('parses connections data correctly', () => { - const mockInfraData: InfraMonitoringMultiResponse = { - data: [], - series: { - pg_stat_database_num_backends: { - format: 'number', - total: 150, - totalAverage: 25.5, - yAxisLimit: 100, - }, - }, - } + it('returns the peak value across the window, not totalAverage', () => { + const mockInfraData = buildResponse([4, 4, 6, 4, 5, 4]) + // totalAverage in series is intentionally stale to ensure we ignore it + mockInfraData.series.pg_stat_database_num_backends.totalAverage = 25 - const mockMaxData = { maxConnections: 100 } + const result = parseConnectionsData(mockInfraData, { maxConnections: 100 }) - const result = parseConnectionsData(mockInfraData, mockMaxData) - - expect(result).toEqual({ current: 26, max: 100 }) // 25.5 rounded to 26 + expect(result).toEqual({ peak: 6, max: 100 }) }) - it('handles string values for connections', () => { - const mockInfraData: InfraMonitoringMultiResponse = { - data: [], - series: { - pg_stat_database_num_backends: { - format: 'number', - total: 150, - totalAverage: '30.7', - yAxisLimit: 100, - }, - }, - } + it('rounds the peak value', () => { + const mockInfraData = buildResponse([3, 5.6, 4]) - const mockMaxData = { maxConnections: 100 } + const result = parseConnectionsData(mockInfraData, { maxConnections: 100 }) - const result = parseConnectionsData(mockInfraData, mockMaxData) - - expect(result).toEqual({ current: 31, max: 100 }) // 30.7 rounded to 31 + expect(result).toEqual({ peak: 6, max: 100 }) }) - it('returns current connections even when maxConnectionsData is undefined', () => { - const mockInfraData: InfraMonitoringMultiResponse = { - data: [], - series: { - pg_stat_database_num_backends: { - format: 'number', - total: 150, - totalAverage: 25, - yAxisLimit: 100, - }, - }, - } + it('handles string values when computing peak', () => { + const mockInfraData = buildResponse(['4', '7', '5.4']) + + const result = parseConnectionsData(mockInfraData, { maxConnections: 100 }) + + expect(result).toEqual({ peak: 7, max: 100 }) + }) + + it('skips missing values when computing peak', () => { + const mockInfraData = buildResponse([5, undefined, 7, undefined]) + + const result = parseConnectionsData(mockInfraData, { maxConnections: 100 }) + + expect(result).toEqual({ peak: 7, max: 100 }) + }) + + it('skips empty-string values when computing peak', () => { + const mockInfraData = buildResponse(['5', '', '7', '']) + + const result = parseConnectionsData(mockInfraData, { maxConnections: 100 }) + + expect(result).toEqual({ peak: 7, max: 100 }) + }) + + it('returns peak connections even when maxConnectionsData is undefined', () => { + const mockInfraData = buildResponse([4, 9, 6]) const result = parseConnectionsData(mockInfraData, undefined) - expect(result).toEqual({ current: 25, max: 0 }) + expect(result).toEqual({ peak: 9, max: 0 }) }) it('returns 0 max when maxConnections is missing from data object', () => { - const mockInfraData: InfraMonitoringMultiResponse = { - data: [], - series: { - pg_stat_database_num_backends: { - format: 'number', - total: 150, - totalAverage: 25, - yAxisLimit: 100, - }, - }, - } + const mockInfraData = buildResponse([4]) - const mockMaxData = {} + const result = parseConnectionsData(mockInfraData, {}) - const result = parseConnectionsData(mockInfraData, mockMaxData) - - expect(result).toEqual({ current: 25, max: 0 }) + expect(result).toEqual({ peak: 4, max: 0 }) }) - it('returns 0 current when connections metric is missing', () => { + it('returns 0 peak when data array is empty', () => { const mockInfraData: InfraMonitoringMultiResponse = { data: [], series: {}, } - const mockMaxData = { maxConnections: 100 } + const result = parseConnectionsData(mockInfraData, { maxConnections: 100 }) - const result = parseConnectionsData(mockInfraData, mockMaxData) + expect(result).toEqual({ peak: 0, max: 100 }) + }) - expect(result).toEqual({ current: 0, max: 100 }) + it('returns 0 peak when connections metric is missing from data points', () => { + const mockInfraData: InfraMonitoringMultiResponse = { + data: [ + { + period_start: '2026-05-22T00:00:00.000Z', + values: { avg_cpu_usage: '50' }, + }, + ], + series: {}, + } + + const result = parseConnectionsData(mockInfraData, { maxConnections: 100 }) + + expect(result).toEqual({ peak: 0, max: 100 }) }) it('handles single-response format (legacy)', () => { @@ -300,10 +311,8 @@ describe('parseConnectionsData', () => { yAxisLimit: 100, } - const mockMaxData = { maxConnections: 100 } + const result = parseConnectionsData(mockInfraData, { maxConnections: 100 }) - const result = parseConnectionsData(mockInfraData, mockMaxData) - - expect(result).toEqual({ current: 0, max: 100 }) + expect(result).toEqual({ peak: 0, max: 100 }) }) }) diff --git a/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.utils.ts b/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.utils.ts index 03cf8e4ebbc..85ae7b5f058 100644 --- a/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.utils.ts +++ b/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.utils.ts @@ -64,7 +64,7 @@ export function parseInfrastructureMetrics( } type ConnectionsData = { - current: number + peak: number max: number } @@ -76,15 +76,21 @@ export function parseConnectionsData( infraData: InfraMonitoringResponse | undefined, maxConnectionsData: MaxConnectionsData | undefined ): ConnectionsData { - if (!infraData) { - return { current: 0, max: 0 } + const max = maxConnectionsData?.maxConnections ?? 0 + + if (!infraData || !('series' in infraData)) { + return { peak: 0, max } } - const series = 'series' in infraData ? infraData.series : {} + // Show the highest connection count observed in the selected window rather + // than the window's totalAverage. The average varies with bucket granularity + // (e.g. 1h vs 1m) and is hard to reason about; peak is interval-stable and + // the more actionable signal for headroom against the connection limit. + let peak = 0 + for (const point of infraData.data ?? []) { + const n = parseNumericValue(point?.values?.pg_stat_database_num_backends) + if (n > peak) peak = n + } - const currentVal = series.pg_stat_database_num_backends?.totalAverage - const current = Math.round(parseNumericValue(currentVal)) - const max = maxConnectionsData?.maxConnections || 0 - - return { current, max } + return { peak: Math.round(peak), max } } diff --git a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceNode.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceNode.tsx index 203ecbb0b12..f6a3427ba7c 100644 --- a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceNode.tsx +++ b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceNode.tsx @@ -201,7 +201,7 @@ export const PrimaryNode = ({ data }: NodeProps>) => { <> · - {connections.current}/{connections.max} conns + {connections.peak}/{connections.max} conns )} diff --git a/apps/studio/hooks/analytics/useComputeMetrics.ts b/apps/studio/hooks/analytics/useComputeMetrics.ts index 37b84320451..6ca5e0e42e6 100644 --- a/apps/studio/hooks/analytics/useComputeMetrics.ts +++ b/apps/studio/hooks/analytics/useComputeMetrics.ts @@ -13,7 +13,7 @@ export type ComputeMetrics = { cpu: number disk: number memory: number - connections: { current: number; max: number } + connections: { peak: number; max: number } isLoading: boolean isError: boolean } From 289accd7d4969ee60dbe9e08215100a0f59d34a7 Mon Sep 17 00:00:00 2001 From: Ali Waseem Date: Tue, 9 Jun 2026 08:25:29 -0600 Subject: [PATCH 058/134] chore: Update time from 10 to 20 minutes for pause projects fallback (#46479) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Minor update for long running state thresholds when updating project sizes ## Summary by CodeRabbit * **Chores** * Increased the minimum threshold for recognizing long-running operations from 10 to 20 minutes, reducing premature fallback behavior and improving stability for longer tasks. * **Tests** * Updated test suite to validate the new 20-minute threshold across default, missing, small, and larger restore scenarios. --- apps/studio/lib/project-transition-state.ts | 2 +- apps/studio/lib/restore-estimate.test.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/studio/lib/project-transition-state.ts b/apps/studio/lib/project-transition-state.ts index 871533bc81d..ae46dec73ca 100644 --- a/apps/studio/lib/project-transition-state.ts +++ b/apps/studio/lib/project-transition-state.ts @@ -1,6 +1,6 @@ import { safeLocalStorage } from 'common' -export const FALLBACK_LONG_RUNNING_STATE_THRESHOLD_MINUTES = 10 +export const FALLBACK_LONG_RUNNING_STATE_THRESHOLD_MINUTES = 20 // Persist long enough for same-browser reloads, but not so long that a later transition reuses stale state. export const MAX_PERSISTED_TRANSITION_AGE_HOURS = 24 diff --git a/apps/studio/lib/restore-estimate.test.ts b/apps/studio/lib/restore-estimate.test.ts index 3ad94014e70..1f1d5bdf532 100644 --- a/apps/studio/lib/restore-estimate.test.ts +++ b/apps/studio/lib/restore-estimate.test.ts @@ -11,14 +11,14 @@ describe('restore-estimate', () => { expect(estimateRestoreTimeFromSizeGb(21_000)).toBeCloseTo(723, 0) }) - it('uses a 10 minute floor when size is missing or small', () => { - expect(getRestoreLongRunningThresholdMinutes()).toBe(10) - expect(getRestoreLongRunningThresholdMinutes(null)).toBe(10) - expect(getRestoreLongRunningThresholdMinutes(100)).toBe(10) + it('uses a 20 minute floor when size is missing or small', () => { + expect(getRestoreLongRunningThresholdMinutes()).toBe(20) + expect(getRestoreLongRunningThresholdMinutes(null)).toBe(20) + expect(getRestoreLongRunningThresholdMinutes(100)).toBe(20) }) it('scales the long-running threshold for larger restores', () => { - expect(getRestoreLongRunningThresholdMinutes(200)).toBe(15) + expect(getRestoreLongRunningThresholdMinutes(200)).toBe(20) expect(getRestoreLongRunningThresholdMinutes(500)).toBe(31) expect(getRestoreLongRunningThresholdMinutes(1_000)).toBe(56) }) From 2d422e4d9dcd684eaad517f7b4b77b15aebc384b Mon Sep 17 00:00:00 2001 From: "Andrey A." <56412611+aantti@users.noreply.github.com> Date: Tue, 9 Jun 2026 16:43:55 +0200 Subject: [PATCH 059/134] fix(self-hosted): use subshell for terminal checks in setup.sh (#46779) --- docker/setup.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker/setup.sh b/docker/setup.sh index 9a2276664ca..4312c65bbd2 100755 --- a/docker/setup.sh +++ b/docker/setup.sh @@ -67,7 +67,7 @@ die() { printf "ERROR: %s\n" "$*" >&2; exit 1; } # Falls back to the default with -y or when no controlling terminal exists. ask() { # ask -> echoes chosen value - if [ "$ASSUME_YES" = "1" ] || ! { : > /dev/tty; } 2>/dev/null; then + if [ "$ASSUME_YES" = "1" ] || ! ( : < /dev/tty ) 2>/dev/null; then printf '%s' "$2" return fi @@ -281,8 +281,8 @@ current_site_url=$(read_env SITE_URL) [ -z "$current_api_url" ] && current_api_url="$current_public_url" [ -z "$current_site_url" ] && current_site_url="http://localhost:3000" -if [ "$ASSUME_YES" = "1" ] || ! { : > /dev/tty; } 2>/dev/null; then - log "Non-interactive: keeping default URLs (edit .env to change)" +if [ "$ASSUME_YES" = "1" ] || ! ( : < /dev/tty ) 2>/dev/null; then + log "Non-interactive: using default URLs (edit .env to change)" else echo "" echo "Configure the main URLs (press Enter to accept the default)." From 1aed2169de78bb06fa892a337a6825bbd7ebbaa5 Mon Sep 17 00:00:00 2001 From: "supabase-supabase-autofixer[bot]" <248690971+supabase-supabase-autofixer[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 19:17:12 +0300 Subject: [PATCH 060/134] docs: update js sdk docs (2.108.1) (#46785) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates JS sdk documentation following stable release. Ran `make download.tsdoc.v2` in apps/docs/spec and refreshed the reference-content snapshot. **Details:** - **Version:** `2.108.1` - **Source:** `manual` - **Changes:** Regenerated tsdoc files from latest spec files 🤖 Auto-generated from @supabase/supabase-js stable release. Co-authored-by: mandarini <6603745+mandarini@users.noreply.github.com> --- .../build-reference-content.v2.json | 508 +++++++----------- 1 file changed, 189 insertions(+), 319 deletions(-) diff --git a/apps/docs/scripts/__snapshots__/build-reference-content.v2.json b/apps/docs/scripts/__snapshots__/build-reference-content.v2.json index d7d17c8dd43..f15c6ac0e19 100644 --- a/apps/docs/scripts/__snapshots__/build-reference-content.v2.json +++ b/apps/docs/scripts/__snapshots__/build-reference-content.v2.json @@ -42,13 +42,6 @@ "product": "database", "type": "function" }, - "geojson": { - "id": "geojson", - "title": "geojson", - "slug": "geojson", - "product": "database", - "type": "function" - }, "insert": { "id": "insert", "title": "insert", @@ -56,34 +49,6 @@ "product": "database", "type": "function" }, - "maxaffected": { - "id": "maxaffected", - "title": "maxAffected", - "slug": "maxaffected", - "product": "database", - "type": "function" - }, - "retry": { - "id": "retry", - "title": "retry", - "slug": "retry", - "product": "database", - "type": "function" - }, - "returns": { - "id": "returns", - "title": "returns", - "slug": "returns", - "product": "database", - "type": "function" - }, - "rollback": { - "id": "rollback", - "title": "rollback", - "slug": "rollback", - "product": "database", - "type": "function" - }, "rpc": { "id": "rpc", "title": "rpc", @@ -105,20 +70,6 @@ "product": "database", "type": "function" }, - "setheader": { - "id": "setheader", - "title": "setHeader", - "slug": "setheader", - "product": "database", - "type": "function" - }, - "throwonerror": { - "id": "throwonerror", - "title": "throwOnError", - "slug": "throwonerror", - "product": "database", - "type": "function" - }, "update": { "id": "update", "title": "update", @@ -355,6 +306,13 @@ "product": "database", "type": "function" }, + "using-modifiers-geojson": { + "id": "using-modifiers-geojson", + "title": "geojson", + "slug": "using-modifiers-geojson", + "product": "database", + "type": "function" + }, "using-modifiers-limit": { "id": "using-modifiers-limit", "title": "limit", @@ -362,6 +320,13 @@ "product": "database", "type": "function" }, + "using-modifiers-maxaffected": { + "id": "using-modifiers-maxaffected", + "title": "maxAffected", + "slug": "using-modifiers-maxaffected", + "product": "database", + "type": "function" + }, "using-modifiers-maybesingle": { "id": "using-modifiers-maybesingle", "title": "maybeSingle", @@ -390,6 +355,13 @@ "product": "database", "type": "function" }, + "using-modifiers-retry": { + "id": "using-modifiers-retry", + "title": "retry", + "slug": "using-modifiers-retry", + "product": "database", + "type": "function" + }, "using-modifiers-returns": { "id": "using-modifiers-returns", "title": "returns", @@ -397,6 +369,13 @@ "product": "database", "type": "function" }, + "using-modifiers-rollback": { + "id": "using-modifiers-rollback", + "title": "rollback", + "slug": "using-modifiers-rollback", + "product": "database", + "type": "function" + }, "using-modifiers-select": { "id": "using-modifiers-select", "title": "select", @@ -404,6 +383,13 @@ "product": "database", "type": "function" }, + "using-modifiers-setheader": { + "id": "using-modifiers-setheader", + "title": "setHeader", + "slug": "using-modifiers-setheader", + "product": "database", + "type": "function" + }, "using-modifiers-single": { "id": "using-modifiers-single", "title": "single", @@ -418,6 +404,13 @@ "product": "database", "type": "function" }, + "using-modifiers-throwonerror": { + "id": "using-modifiers-throwonerror", + "title": "throwOnError", + "slug": "using-modifiers-throwonerror", + "product": "database", + "type": "function" + }, "auth": { "id": "auth", "title": "Overview", @@ -1716,7 +1709,6 @@ "[Circular]", "[Circular]", "[Circular]", - "[Circular]", "[Circular]" ], "sections": [ @@ -1728,13 +1720,6 @@ "type": "category", "title": "Database", "items": [ - "[Circular]", - "[Circular]", - "[Circular]", - "[Circular]", - "[Circular]", - "[Circular]", - "[Circular]", "[Circular]", "[Circular]", "[Circular]", @@ -1801,6 +1786,12 @@ "[Circular]", "[Circular]", "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", + "[Circular]", "[Circular]" ] } @@ -2088,30 +2079,10 @@ "id": "from", "$ref": "@supabase/postgrest-js.PostgrestClient.from" }, - { - "id": "geojson", - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.geojson" - }, { "id": "insert", "$ref": "@supabase/postgrest-js.PostgrestQueryBuilder.insert" }, - { - "id": "maxaffected", - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.maxAffected" - }, - { - "id": "retry", - "$ref": "@supabase/postgrest-js.PostgrestBuilder.retry" - }, - { - "id": "returns", - "$ref": "@supabase/postgrest-js.PostgrestBuilder.returns" - }, - { - "id": "rollback", - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.rollback" - }, { "id": "rpc", "$ref": "@supabase/postgrest-js.PostgrestClient.rpc" @@ -2124,14 +2095,6 @@ "id": "select", "$ref": "@supabase/postgrest-js.PostgrestQueryBuilder.select" }, - { - "id": "setheader", - "$ref": "@supabase/postgrest-js.PostgrestBuilder.setHeader" - }, - { - "id": "throwonerror", - "$ref": "@supabase/postgrest-js.PostgrestBuilder.throwOnError" - }, { "id": "update", "$ref": "@supabase/postgrest-js.PostgrestQueryBuilder.update" @@ -2309,10 +2272,18 @@ "id": "using-modifiers-explain", "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.explain" }, + { + "id": "using-modifiers-geojson", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.geojson" + }, { "id": "using-modifiers-limit", "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.limit" }, + { + "id": "using-modifiers-maxaffected", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.maxAffected" + }, { "id": "using-modifiers-maybesingle", "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.maybeSingle" @@ -2329,14 +2300,26 @@ "id": "using-modifiers-range", "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.range" }, + { + "id": "using-modifiers-retry", + "$ref": "@supabase/postgrest-js.PostgrestBuilder.retry" + }, { "id": "using-modifiers-returns", - "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.returns" + "$ref": "@supabase/postgrest-js.PostgrestBuilder.returns" + }, + { + "id": "using-modifiers-rollback", + "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.rollback" }, { "id": "using-modifiers-select", "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.select" }, + { + "id": "using-modifiers-setheader", + "$ref": "@supabase/postgrest-js.PostgrestBuilder.setHeader" + }, { "id": "using-modifiers-single", "$ref": "@supabase/postgrest-js.PostgrestFilterBuilder.single" @@ -2345,6 +2328,10 @@ "id": "using-modifiers-stripnulls", "$ref": "@supabase/postgrest-js.PostgrestBuilder.stripNulls" }, + { + "id": "using-modifiers-throwonerror", + "$ref": "@supabase/postgrest-js.PostgrestBuilder.throwOnError" + }, { "id": "auth", "title": "Overview", @@ -11306,7 +11293,7 @@ } }, "comment": { - "shortText": "Initializes the client session either from the url or from storage.\nThis method is automatically called when instantiating the client, but should also be called\nmanually when checking for an error from an auth redirect (oauth, magiclink, password recovery, etc)." + "shortText": "Initialize the auth client by loading the session from storage or\ndetecting it from the URL after an OAuth, magic-link, or password-recovery\nredirect.\n\n**Most callers do not need to invoke this directly.** The client calls it\nautomatically during construction, and to react to sign-in events (including\npost-redirect events) you should subscribe to `onAuthStateChange` rather\nthan awaiting `initialize()`.\n\nYou only need to call it manually when you have opted out of the automatic\ncall by passing `skipAutoInitialize: true` — for example, in an SSR context\nwhere you need to control initialization timing. In that case, awaiting\n`initialize()` returns the resolved session result (or any error encountered\nwhile detecting it from the URL)." } }, "@supabase/auth-js.GoTrueClient.isThrowOnErrorEnabled": { @@ -34904,6 +34891,9 @@ "type": { "type": "intrinsic", "name": "string" + }, + "comment": { + "shortText": "HTTP header name" } }, { @@ -34911,6 +34901,9 @@ "type": { "type": "intrinsic", "name": "string" + }, + "comment": { + "shortText": "HTTP header value" } } ], @@ -34921,7 +34914,7 @@ } }, "comment": { - "shortText": "Set an HTTP header for the request." + "shortText": "Set an HTTP header on this single PostgREST request, overriding any header\nwith the same name set on the client.\n\nThis is an advanced escape hatch for one-off needs (passing a custom\n`Authorization` for a single query, attaching a tracing header, etc.).\nMost callers do not need it: configure client-wide headers via the\n`headers` option when constructing the client, and authentication via\nSupabase Auth." } }, "@supabase/postgrest-js.PostgrestBuilder.stripNulls": { @@ -35047,6 +35040,12 @@ "@supabase/postgrest-js.PostgrestBuilder.throwOnError": { "name": "@supabase/postgrest-js.PostgrestBuilder.throwOnError", "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, "comment": { "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.\n\nhttps://github.com/supabase/supabase-js/issues/92" } @@ -38600,7 +38599,14 @@ } }, "comment": { - "shortText": "Rollback the query.\n\n`data` will still be returned, but the query is not committed." + "shortText": "Dry-run this request: execute the query but discard the changes.\n\nServer-side, PostgREST runs the query inside a transaction and rolls it back\ninstead of committing. The response still contains the data that *would* have\nbeen returned — `RETURNING` clauses execute and RLS, triggers, and constraints\nare all evaluated — but no row is actually inserted, updated, or deleted.\n\nThis affects only the single request it is chained to. The JS caller has no\nhandle on the transaction: supabase-js does not group multiple queries into\none transaction. For multi-statement transactional logic, use a database\nfunction (`supabase.rpc(...)`).\n\nSets the `Prefer: tx=rollback` header. See PostgREST's docs on transaction\npreferences for the underlying mechanism.", + "examples": [ + { + "id": "validate-an-insert-without-persisting", + "name": "Validate an insert without persisting", + "code": "```ts\nconst { data, error } = await supabase\n .from('countries')\n .insert({ name: 'France' })\n .select()\n .rollback()\n// `data` shows what would have been inserted; nothing is saved.\n```" + } + ] } }, "@supabase/postgrest-js.PostgrestFilterBuilder.select": { @@ -38647,6 +38653,9 @@ "type": { "type": "intrinsic", "name": "string" + }, + "comment": { + "shortText": "HTTP header name" } }, { @@ -38654,6 +38663,9 @@ "type": { "type": "intrinsic", "name": "string" + }, + "comment": { + "shortText": "HTTP header value" } } ], @@ -38664,7 +38676,7 @@ } }, "comment": { - "shortText": "Set an HTTP header for the request." + "shortText": "Set an HTTP header on this single PostgREST request, overriding any header\nwith the same name set on the client.\n\nThis is an advanced escape hatch for one-off needs (passing a custom\n`Authorization` for a single query, attaching a tracing header, etc.).\nMost callers do not need it: configure client-wide headers via the\n`headers` option when constructing the client, and authentication via\nSupabase Auth." } }, "@supabase/postgrest-js.PostgrestFilterBuilder.single": { @@ -38891,118 +38903,7 @@ "type": "function", "params": [ { - "name": "value", - "type": { - "type": "union", - "name": "PostgrestSingleResponse", - "subTypes": [ - { - "type": "object", - "name": "PostgrestResponseSuccess", - "properties": [ - { - "name": "count", - "type": { - "type": "union", - "subTypes": [ - { - "type": "literal", - "value": null - }, - { - "type": "intrinsic", - "name": "number" - } - ] - } - }, - { - "name": "data", - "type": { - "type": "nameOnly", - "name": "@supabase/postgrest-js.default.Result" - } - }, - { - "name": "error", - "type": { - "type": "literal", - "value": null - } - }, - { - "name": "status", - "type": { - "type": "intrinsic", - "name": "number" - } - }, - { - "name": "statusText", - "type": { - "type": "intrinsic", - "name": "string" - } - }, - { - "name": "success", - "type": { - "type": "literal", - "value": true - } - } - ] - }, - { - "type": "object", - "name": "PostgrestResponseFailure", - "properties": [ - { - "name": "count", - "type": { - "type": "literal", - "value": null - } - }, - { - "name": "data", - "type": { - "type": "literal", - "value": null - } - }, - { - "name": "error", - "type": { - "type": "nameOnly", - "name": "PostgrestError" - } - }, - { - "name": "status", - "type": { - "type": "intrinsic", - "name": "number" - } - }, - { - "name": "statusText", - "type": { - "type": "intrinsic", - "name": "string" - } - }, - { - "name": "success", - "type": { - "type": "literal", - "value": false - } - } - ] - } - ] - } + "name": "value" } ], "ret": { @@ -39085,6 +38986,12 @@ "@supabase/postgrest-js.PostgrestFilterBuilder.throwOnError": { "name": "@supabase/postgrest-js.PostgrestFilterBuilder.throwOnError", "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, "comment": { "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.\n\nhttps://github.com/supabase/supabase-js/issues/92" } @@ -40830,7 +40737,14 @@ } }, "comment": { - "shortText": "Rollback the query.\n\n`data` will still be returned, but the query is not committed." + "shortText": "Dry-run this request: execute the query but discard the changes.\n\nServer-side, PostgREST runs the query inside a transaction and rolls it back\ninstead of committing. The response still contains the data that *would* have\nbeen returned — `RETURNING` clauses execute and RLS, triggers, and constraints\nare all evaluated — but no row is actually inserted, updated, or deleted.\n\nThis affects only the single request it is chained to. The JS caller has no\nhandle on the transaction: supabase-js does not group multiple queries into\none transaction. For multi-statement transactional logic, use a database\nfunction (`supabase.rpc(...)`).\n\nSets the `Prefer: tx=rollback` header. See PostgREST's docs on transaction\npreferences for the underlying mechanism.", + "examples": [ + { + "id": "validate-an-insert-without-persisting", + "name": "Validate an insert without persisting", + "code": "```ts\nconst { data, error } = await supabase\n .from('countries')\n .insert({ name: 'France' })\n .select()\n .rollback()\n// `data` shows what would have been inserted; nothing is saved.\n```" + } + ] } }, "@supabase/postgrest-js.PostgrestTransformBuilder.select": { @@ -40877,6 +40791,9 @@ "type": { "type": "intrinsic", "name": "string" + }, + "comment": { + "shortText": "HTTP header name" } }, { @@ -40884,6 +40801,9 @@ "type": { "type": "intrinsic", "name": "string" + }, + "comment": { + "shortText": "HTTP header value" } } ], @@ -40894,7 +40814,7 @@ } }, "comment": { - "shortText": "Set an HTTP header for the request." + "shortText": "Set an HTTP header on this single PostgREST request, overriding any header\nwith the same name set on the client.\n\nThis is an advanced escape hatch for one-off needs (passing a custom\n`Authorization` for a single query, attaching a tracing header, etc.).\nMost callers do not need it: configure client-wide headers via the\n`headers` option when constructing the client, and authentication via\nSupabase Auth." } }, "@supabase/postgrest-js.PostgrestTransformBuilder.single": { @@ -40961,85 +40881,7 @@ "type": "function", "params": [ { - "name": "value", - "type": { - "type": "union", - "name": "PostgrestSingleResponse", - "subTypes": [ - { - "type": "object", - "name": "PostgrestResponseSuccess", - "properties": [ - { - "name": "count", - "type": { - "type": "union", - "subTypes": [ - "[Circular]", - "[Circular]" - ] - } - }, - { - "name": "data", - "type": { - "type": "nameOnly", - "name": "@supabase/postgrest-js.default.Result" - } - }, - { - "name": "error", - "type": "[Circular]" - }, - { - "name": "status", - "type": "[Circular]" - }, - { - "name": "statusText", - "type": "[Circular]" - }, - { - "name": "success", - "type": "[Circular]" - } - ] - }, - { - "type": "object", - "name": "PostgrestResponseFailure", - "properties": [ - { - "name": "count", - "type": "[Circular]" - }, - { - "name": "data", - "type": "[Circular]" - }, - { - "name": "error", - "type": { - "type": "nameOnly", - "name": "PostgrestError" - } - }, - { - "name": "status", - "type": "[Circular]" - }, - { - "name": "statusText", - "type": "[Circular]" - }, - { - "name": "success", - "type": "[Circular]" - } - ] - } - ] - } + "name": "value" } ], "ret": { @@ -41122,6 +40964,12 @@ "@supabase/postgrest-js.PostgrestTransformBuilder.throwOnError": { "name": "@supabase/postgrest-js.PostgrestTransformBuilder.throwOnError", "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestTransformBuilder" + } + }, "comment": { "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.\n\nhttps://github.com/supabase/supabase-js/issues/92" } @@ -63959,7 +63807,7 @@ } }, "comment": { - "shortText": "Initializes the client session either from the url or from storage.\nThis method is automatically called when instantiating the client, but should also be called\nmanually when checking for an error from an auth redirect (oauth, magiclink, password recovery, etc)." + "shortText": "Initialize the auth client by loading the session from storage or\ndetecting it from the URL after an OAuth, magic-link, or password-recovery\nredirect.\n\n**Most callers do not need to invoke this directly.** The client calls it\nautomatically during construction, and to react to sign-in events (including\npost-redirect events) you should subscribe to `onAuthStateChange` rather\nthan awaiting `initialize()`.\n\nYou only need to call it manually when you have opted out of the automatic\ncall by passing `skipAutoInitialize: true` — for example, in an SSR context\nwhere you need to control initialization timing. In that case, awaiting\n`initialize()` returns the resolved session result (or any error encountered\nwhile detecting it from the URL)." } }, "@supabase/supabase-js.GoTrueClient.isThrowOnErrorEnabled": { @@ -78652,6 +78500,9 @@ "type": { "type": "intrinsic", "name": "string" + }, + "comment": { + "shortText": "HTTP header name" } }, { @@ -78659,6 +78510,9 @@ "type": { "type": "intrinsic", "name": "string" + }, + "comment": { + "shortText": "HTTP header value" } } ], @@ -78669,7 +78523,7 @@ } }, "comment": { - "shortText": "Set an HTTP header for the request." + "shortText": "Set an HTTP header on this single PostgREST request, overriding any header\nwith the same name set on the client.\n\nThis is an advanced escape hatch for one-off needs (passing a custom\n`Authorization` for a single query, attaching a tracing header, etc.).\nMost callers do not need it: configure client-wide headers via the\n`headers` option when constructing the client, and authentication via\nSupabase Auth." } }, "@supabase/supabase-js.PostgrestBuilder.stripNulls": { @@ -78795,6 +78649,12 @@ "@supabase/supabase-js.PostgrestBuilder.throwOnError": { "name": "@supabase/supabase-js.PostgrestBuilder.throwOnError", "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestBuilder" + } + }, "comment": { "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.\n\nhttps://github.com/supabase/supabase-js/issues/92" } @@ -81620,7 +81480,14 @@ } }, "comment": { - "shortText": "Rollback the query.\n\n`data` will still be returned, but the query is not committed." + "shortText": "Dry-run this request: execute the query but discard the changes.\n\nServer-side, PostgREST runs the query inside a transaction and rolls it back\ninstead of committing. The response still contains the data that *would* have\nbeen returned — `RETURNING` clauses execute and RLS, triggers, and constraints\nare all evaluated — but no row is actually inserted, updated, or deleted.\n\nThis affects only the single request it is chained to. The JS caller has no\nhandle on the transaction: supabase-js does not group multiple queries into\none transaction. For multi-statement transactional logic, use a database\nfunction (`supabase.rpc(...)`).\n\nSets the `Prefer: tx=rollback` header. See PostgREST's docs on transaction\npreferences for the underlying mechanism.", + "examples": [ + { + "id": "validate-an-insert-without-persisting", + "name": "Validate an insert without persisting", + "code": "```ts\nconst { data, error } = await supabase\n .from('countries')\n .insert({ name: 'France' })\n .select()\n .rollback()\n// `data` shows what would have been inserted; nothing is saved.\n```" + } + ] } }, "@supabase/supabase-js.PostgrestFilterBuilder.select": { @@ -81667,6 +81534,9 @@ "type": { "type": "intrinsic", "name": "string" + }, + "comment": { + "shortText": "HTTP header name" } }, { @@ -81674,6 +81544,9 @@ "type": { "type": "intrinsic", "name": "string" + }, + "comment": { + "shortText": "HTTP header value" } } ], @@ -81684,7 +81557,7 @@ } }, "comment": { - "shortText": "Set an HTTP header for the request." + "shortText": "Set an HTTP header on this single PostgREST request, overriding any header\nwith the same name set on the client.\n\nThis is an advanced escape hatch for one-off needs (passing a custom\n`Authorization` for a single query, attaching a tracing header, etc.).\nMost callers do not need it: configure client-wide headers via the\n`headers` option when constructing the client, and authentication via\nSupabase Auth." } }, "@supabase/supabase-js.PostgrestFilterBuilder.single": { @@ -81878,21 +81751,7 @@ "type": "function", "params": [ { - "name": "value", - "type": { - "type": "union", - "name": "PostgrestSingleResponse", - "subTypes": [ - { - "type": "nameOnly", - "name": "PostgrestResponseSuccess" - }, - { - "type": "nameOnly", - "name": "PostgrestResponseFailure" - } - ] - } + "name": "value" } ], "ret": { @@ -81975,6 +81834,12 @@ "@supabase/supabase-js.PostgrestFilterBuilder.throwOnError": { "name": "@supabase/supabase-js.PostgrestFilterBuilder.throwOnError", "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestFilterBuilder" + } + }, "comment": { "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.\n\nhttps://github.com/supabase/supabase-js/issues/92" } @@ -83693,7 +83558,14 @@ } }, "comment": { - "shortText": "Rollback the query.\n\n`data` will still be returned, but the query is not committed." + "shortText": "Dry-run this request: execute the query but discard the changes.\n\nServer-side, PostgREST runs the query inside a transaction and rolls it back\ninstead of committing. The response still contains the data that *would* have\nbeen returned — `RETURNING` clauses execute and RLS, triggers, and constraints\nare all evaluated — but no row is actually inserted, updated, or deleted.\n\nThis affects only the single request it is chained to. The JS caller has no\nhandle on the transaction: supabase-js does not group multiple queries into\none transaction. For multi-statement transactional logic, use a database\nfunction (`supabase.rpc(...)`).\n\nSets the `Prefer: tx=rollback` header. See PostgREST's docs on transaction\npreferences for the underlying mechanism.", + "examples": [ + { + "id": "validate-an-insert-without-persisting", + "name": "Validate an insert without persisting", + "code": "```ts\nconst { data, error } = await supabase\n .from('countries')\n .insert({ name: 'France' })\n .select()\n .rollback()\n// `data` shows what would have been inserted; nothing is saved.\n```" + } + ] } }, "@supabase/supabase-js.PostgrestTransformBuilder.select": { @@ -83740,6 +83612,9 @@ "type": { "type": "intrinsic", "name": "string" + }, + "comment": { + "shortText": "HTTP header name" } }, { @@ -83747,6 +83622,9 @@ "type": { "type": "intrinsic", "name": "string" + }, + "comment": { + "shortText": "HTTP header value" } } ], @@ -83757,7 +83635,7 @@ } }, "comment": { - "shortText": "Set an HTTP header for the request." + "shortText": "Set an HTTP header on this single PostgREST request, overriding any header\nwith the same name set on the client.\n\nThis is an advanced escape hatch for one-off needs (passing a custom\n`Authorization` for a single query, attaching a tracing header, etc.).\nMost callers do not need it: configure client-wide headers via the\n`headers` option when constructing the client, and authentication via\nSupabase Auth." } }, "@supabase/supabase-js.PostgrestTransformBuilder.single": { @@ -83824,21 +83702,7 @@ "type": "function", "params": [ { - "name": "value", - "type": { - "type": "union", - "name": "PostgrestSingleResponse", - "subTypes": [ - { - "type": "nameOnly", - "name": "PostgrestResponseSuccess" - }, - { - "type": "nameOnly", - "name": "PostgrestResponseFailure" - } - ] - } + "name": "value" } ], "ret": { @@ -83921,6 +83785,12 @@ "@supabase/supabase-js.PostgrestTransformBuilder.throwOnError": { "name": "@supabase/supabase-js.PostgrestTransformBuilder.throwOnError", "params": [], + "ret": { + "type": { + "type": "nameOnly", + "name": "PostgrestTransformBuilder" + } + }, "comment": { "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.\n\nhttps://github.com/supabase/supabase-js/issues/92" } From 136a7be98ff01b4169623692ff8aa40868df0500 Mon Sep 17 00:00:00 2001 From: Leandro Pereira Date: Tue, 9 Jun 2026 12:45:34 -0400 Subject: [PATCH 061/134] docs(realtime): troubleshooting WarnSendingBroadcastMessage (#46681) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Guide to troubleshoot a warning that can be emitted by Realtime DB broadcast. Ref: https://github.com/supabase/realtime/pull/1941 Preview: https://docs-git-docs-realtime-warn-send-supabase.vercel.app/docs/guides/troubleshooting/realtime-warn-sending-broadcast-message ## Summary by CodeRabbit * **Documentation** * Added a troubleshooting guide for a broadcast-message warning observed in Postgres logs. * Explains why messages may be dropped when partitions/replication streaming aren’t yet available and when they become available. * Provides diagnostic steps and remediation (ensure a subscriber/client is connected) and guidance for when repeated warnings indicate a real issue requiring error inspection. --------- Co-authored-by: Chris Chinchilla --- ...ealtime-warn-sending-broadcast-message.mdx | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 apps/docs/content/troubleshooting/realtime-warn-sending-broadcast-message.mdx diff --git a/apps/docs/content/troubleshooting/realtime-warn-sending-broadcast-message.mdx b/apps/docs/content/troubleshooting/realtime-warn-sending-broadcast-message.mdx new file mode 100644 index 00000000000..bbdf7013e0a --- /dev/null +++ b/apps/docs/content/troubleshooting/realtime-warn-sending-broadcast-message.mdx @@ -0,0 +1,52 @@ +--- +title = "Realtime: WarnSendingBroadcastMessage when broadcasting from the database" +date_created = "2026-06-05T00:00:00+00:00" +topics = [ "realtime" ] +keywords = [ "broadcast", "realtime.send", "realtime.send_binary", "WarnSendingBroadcastMessage", "partition", "messages", "replication" ] +database_id = "027fba24-c7bc-4c54-9e6b-6f13ec85ad56" +--- + +If you broadcast from the database with `realtime.send` or `realtime.send_binary`, you may see this in your Postgres logs: + +``` +WARNING: WarnSendingBroadcastMessage: +``` + +It means the function could not insert the row into `realtime.messages`, so that message was not broadcast. This shows up in an edge case where the message would not have reached anyone anyway. This guide explains when that is the case and when the warning points to a real problem. + +## Why the dropped message would not have been delivered + +Realtime broadcasts database changes by streaming the `realtime.messages` table through a replication slot. That slot only starts once a client connects over WebSocket and the connection process begins streaming. The slot is temporary and does not replay history, so it only delivers messages inserted _after_ a client connected. + +So if you call `realtime.send` while nobody is connected, the message would not reach anyone even if the insert succeeded. No connection means no listener. Dropping it is the same outcome. + +This is why the log line is a warning and not an error. + +## What usually triggers it + +The most common cause is a missing daily partition on `realtime.messages`. The table is partitioned by day, and `realtime.send` or `realtime.send_binary` does not create partitions itself. If no partition exists for the current day, the insert fails with a message like `no partition of relation "messages" found for row`, and you get the `WarnSendingBroadcastMessage` warning. + +Partitions are created in three occasions: + +| Where | When it runs | +| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| A client connects over WebSocket | The first time a client joins a channel for the project, after database migrations run | +| The tenant health check endpoint | When the health endpoint is called and the project either has an active database connection or has connected clients. Opening the Realtime section of your project dashboard calls this endpoint | +| The scheduled janitor | Periodically (roughly every 4 hours), when it deletes old messages and recreates the partition window. It only runs for projects that have had a connection established at least once | + +Each of these creates a rolling window of partitions: yesterday, today, and the next three days. + + + +Calling `realtime.send` / `realtime.send_binary`, the broadcast REST endpoint, and subscribe or replication operations do not create partitions. So a project that has never had a WebSocket client connect, and whose health check and janitor have not yet run for the day, has no partition to insert into. Broadcasting from the database before that point produces the warning. + + + +## How to avoid it + +- Connect a client before broadcasting from the database. A live WebSocket connection both creates the partitions and starts the consumer that actually receives the message. +- If you broadcast from the database on a schedule, make sure at least one subscriber is connected when you send. Otherwise the messages have no destination. + +## When it is a real problem + +If you see this warning repeatedly while clients are connected and partitions exist, the insert is failing for another reason. The actual cause is in the `` part of the log line (the underlying `SQLERRM`). Check your Postgres logs for that text rather than assuming it is a missing partition. Common examples are a constraint violation or a permissions issue on `realtime.messages`. From 9c572a56fd46c5bd41eaabaa2272e8917ec3d9bf Mon Sep 17 00:00:00 2001 From: Jordi Enric <37541088+jordienr@users.noreply.github.com> Date: Tue, 9 Jun 2026 18:46:37 +0200 Subject: [PATCH 062/134] feat(logs): add realtime, supavisor, and pgbouncer to unified logs (#46786) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problem The unified logs view was missing three log sources that the backend already returns: Realtime (`realtime_logs`), Supavisor (`supavisor_logs`), and PgBouncer (`pgbouncer_logs`). Users had no way to filter or view logs from these services in the unified view. ## Fix - Added `realtime`, `supavisor`, and `pgbouncer` to `LOG_TYPE_PREDICATE` and `LOG_TYPE_EXPR` in the OTEL query builder so rows from these sources are matched and labeled correctly. - Added the three types to `LOG_TYPES` so filter chips appear in the UI. - Added icons (`Realtime` from the icons package, `Cable` from lucide-react for both pooler types) in `LogTypeIcon.tsx`. - Added display labels in `formatServiceTypeForDisplay` (`Realtime`, `Supavisor`, `PgBouncer`). - Fixed a pre-existing unsafe cast in `ServiceFlowPanel.tsx` where any log type not in the service flow allow-list (like the new types) would produce a truthy `serviceFlowType` and trigger a runtime error on row click. The fix checks against `SERVICE_FLOW_TYPES` before casting. Note: `pg_cron_logs` is not included because the backend otel query does not yet return that source. ## How to test 1. Open unified logs for a project that has Realtime activity. 2. In the log type filter, confirm `realtime`, `supavisor`, and `pgbouncer` chips are visible. 3. Toggle on `realtime` and confirm Realtime logs appear with the correct icon. 4. Click a realtime log row and confirm the detail panel opens on the raw JSON tab without a runtime error. 5. Toggle on `supavisor` or `pgbouncer` and confirm pooler logs appear if the project has connection pooler activity. ## Summary by CodeRabbit * **New Features** * Added support for three new log types — Realtime, Supavisor, and PgBouncer — in Unified Logs with display labels, icons, and filtering/viewing support. * **Bug Fixes / UI Behavior** * Service Flow “Overview” tab now only shows when the service type is recognized, preventing irrelevant overview content for unsupported log sources. --------- Co-authored-by: Claude Sonnet 4.6 --- .../UnifiedLogs/ServiceFlowPanel.tsx | 9 +++- .../UnifiedLogs/UnifiedLogs.constants.tsx | 11 ++++- .../UnifiedLogs/UnifiedLogs.queries.ts | 6 +++ .../UnifiedLogs/UnifiedLogs.utils.ts | 3 ++ .../UnifiedLogs/components/LogTypeIcon.tsx | 47 +++++++++---------- packages/common/telemetry-constants.ts | 10 +++- 6 files changed, 58 insertions(+), 28 deletions(-) diff --git a/apps/studio/components/interfaces/UnifiedLogs/ServiceFlowPanel.tsx b/apps/studio/components/interfaces/UnifiedLogs/ServiceFlowPanel.tsx index c4a7723148a..ff6058b87c7 100644 --- a/apps/studio/components/interfaces/UnifiedLogs/ServiceFlowPanel.tsx +++ b/apps/studio/components/interfaces/UnifiedLogs/ServiceFlowPanel.tsx @@ -30,6 +30,7 @@ import { QuerySearchParamsType } from './UnifiedLogs.types' import { getRowTimestampMs } from './UnifiedLogs.utils' import { useDataTable } from '@/components/ui/DataTable/providers/DataTableProvider' import { + SERVICE_FLOW_TYPES, ServiceFlowType, useUnifiedLogInspectionQuery, } from '@/data/logs/unified-log-inspection-query' @@ -63,8 +64,12 @@ export function ServiceFlowPanel({ }, [selectedRowKey]) const logType = selectedRow?.log_type - const serviceFlowType: ServiceFlowType | undefined = - logType === 'edge function' ? 'edge-function' : (logType as ServiceFlowType) + const normalizedLogType = logType === 'edge function' ? 'edge-function' : logType + const serviceFlowType: ServiceFlowType | undefined = SERVICE_FLOW_TYPES.includes( + normalizedLogType as ServiceFlowType + ) + ? (normalizedLogType as ServiceFlowType) + : undefined const shouldShowServiceFlow = !!serviceFlowType useEffect(() => { diff --git a/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.constants.tsx b/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.constants.tsx index 47e7b5c2ab7..8abac9cca6d 100644 --- a/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.constants.tsx +++ b/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.constants.tsx @@ -16,7 +16,16 @@ import { export const REGIONS = ['ams', 'fra', 'gru', 'hkg', 'iad', 'syd'] as const export const METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'] as const -export const LOG_TYPES = ['postgres', 'postgrest', 'auth', 'storage', 'edge function'] as const +export const LOG_TYPES = [ + 'postgres', + 'postgrest', + 'auth', + 'storage', + 'edge function', + 'realtime', + 'supavisor', + 'pgbouncer', +] as const export const DEFAULT_LOG_TYPES = ['postgres', 'postgrest'] as const const parseAsSort = createParser({ diff --git a/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.queries.ts b/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.queries.ts index 5d111ac7ec2..01839820d90 100644 --- a/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.queries.ts +++ b/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.queries.ts @@ -53,6 +53,9 @@ const LOG_TYPE_PREDICATE: Record = { postgres: safeSql`source = 'postgres_logs'`, 'edge function': safeSql`source = 'function_edge_logs'`, auth: safeSql`source = 'auth_logs'`, + realtime: safeSql`source = 'realtime_logs'`, + supavisor: safeSql`source = 'supavisor_logs'`, + pgbouncer: safeSql`source = 'pgbouncer_logs'`, } // Derived `log_type` column for SELECT / GROUP BY / countIf use. @@ -63,6 +66,9 @@ const LOG_TYPE_EXPR: SafeLogSqlFragment = safeSql`CASE WHEN source = 'postgres_logs' THEN 'postgres' WHEN source = 'function_edge_logs' THEN 'edge function' WHEN source = 'auth_logs' THEN 'auth' + WHEN source = 'realtime_logs' THEN 'realtime' + WHEN source = 'supavisor_logs' THEN 'supavisor' + WHEN source = 'pgbouncer_logs' THEN 'pgbouncer' ELSE source END` diff --git a/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.utils.ts b/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.utils.ts index c526a0cfcdd..bc2c09fea07 100644 --- a/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.utils.ts +++ b/apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.utils.ts @@ -95,6 +95,9 @@ export function formatServiceTypeForDisplay(serviceType: string): string { postgres: 'Postgres', auth: 'Auth', storage: 'Storage', + realtime: 'Realtime', + supavisor: 'Supavisor', + pgbouncer: 'PgBouncer', } return specialCases[serviceType.toLowerCase()] || serviceType diff --git a/apps/studio/components/interfaces/UnifiedLogs/components/LogTypeIcon.tsx b/apps/studio/components/interfaces/UnifiedLogs/components/LogTypeIcon.tsx index 2d85e47a3aa..73134ae74fe 100644 --- a/apps/studio/components/interfaces/UnifiedLogs/components/LogTypeIcon.tsx +++ b/apps/studio/components/interfaces/UnifiedLogs/components/LogTypeIcon.tsx @@ -1,5 +1,5 @@ -import { Auth, EdgeFunctions, Storage } from 'icons' -import { Box, Code2, Database } from 'lucide-react' +import { Auth, EdgeFunctions, Realtime, Storage } from 'icons' +import { Box, Cable, Code2, Database } from 'lucide-react' import { Tooltip, TooltipContent, TooltipTrigger } from 'ui' import { type LOG_TYPES } from '../UnifiedLogs.constants' @@ -11,38 +11,37 @@ interface LogTypeIconProps { className?: string } +type IconComponent = React.ComponentType<{ + size?: number + strokeWidth?: number + className?: string +}> + +// [Alaister]: commented out types coming in the future +// edge: Globe, +const ICON_MAP: Partial> = { + postgrest: Code2, + auth: Auth, + 'edge function': EdgeFunctions, + postgres: Database, + storage: Storage, + realtime: Realtime, + supavisor: Cable, + pgbouncer: Cable, +} + export const LogTypeIcon = ({ type, size = 16, strokeWidth = 1.5, className, }: LogTypeIconProps) => { - // [Alaister]: commented out types coming in the future - const iconMap: Record<(typeof LOG_TYPES)[number], () => React.ReactNode> = { - // edge: () => , - postgrest: () => , - auth: () => , - 'edge function': () => ( - - ), - postgres: () => , - // function_events: () => ( - // - // ), - // supavisor: () => , - // postgres_upgrade: () => , - storage: () => , - - // cron: () => , - } - - const IconComponent = - iconMap[type] || (() => ) + const Icon = ICON_MAP[type] ?? Box return ( - +
{type}
diff --git a/packages/common/telemetry-constants.ts b/packages/common/telemetry-constants.ts index a06cd36d605..d000c1e47ee 100644 --- a/packages/common/telemetry-constants.ts +++ b/packages/common/telemetry-constants.ts @@ -3154,7 +3154,15 @@ export interface UnifiedLogsRowClickedEvent { * Server values are validated against this set by zod (UnifiedLogs.schema.ts) before * reaching the table; anything else is rejected upstream so the union here is exhaustive. */ - logType: 'postgres' | 'postgrest' | 'auth' | 'storage' | 'edge function' + logType: + | 'postgres' + | 'postgrest' + | 'auth' + | 'storage' + | 'edge function' + | 'realtime' + | 'supavisor' + | 'pgbouncer' } groups: TelemetryGroups } From 996d2b7c1e8ee85ca584160963f26b67d63b7e56 Mon Sep 17 00:00:00 2001 From: Hanefi Onaldi Date: Tue, 9 Jun 2026 20:27:55 +0300 Subject: [PATCH 063/134] =?UTF-8?q?Add=20Hanefi=20=C3=96nald=C4=B1=20to=20?= =?UTF-8?q?humans.txt=20(#46782)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Docs update ## What is the current behavior? https://supabase.com/humans.txt does not list my name. ## What is the new behavior? https://supabase.com/humans.txt will list my name ## Additional context Started yesterday as a Postgres Engineer. ## Summary by CodeRabbit * **Chores** * Updated public team contributor information. --- apps/docs/public/humans.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/docs/public/humans.txt b/apps/docs/public/humans.txt index 8ed0ed04de9..539b9138c86 100644 --- a/apps/docs/public/humans.txt +++ b/apps/docs/public/humans.txt @@ -109,6 +109,7 @@ Greg P Greg Richardson Gregor Vand Guilherme Souza +Hanefi Önaldı Hannah Bowers Hardik Maheshwari Haritabh Gupta From e54ba014c11d62f39878b647054f1cd8e68d8a76 Mon Sep 17 00:00:00 2001 From: Prashant Sridharan <914007+CoolAssPuppy@users.noreply.github.com> Date: Tue, 9 Jun 2026 21:37:42 +0100 Subject: [PATCH 064/134] Fixed a link in the Hosted Postgres page (#46791) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Fixed a missing link in the Hosted Postgres page Added the missing solution pages to the Footer ## Summary by CodeRabbit * **Updates** * Restructured footer Solutions section to dynamically include additional solution categories, providing more comprehensive navigation options * Enhanced Hosted Postgres feature description with a direct link to Multigres for improved accessibility --- apps/www/data/Footer.ts | 19 ++++++++++++++----- apps/www/data/solutions/hosted-postgres.tsx | 13 ++++++++++++- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/apps/www/data/Footer.ts b/apps/www/data/Footer.ts index 19f6e136634..f6839ecc8bd 100644 --- a/apps/www/data/Footer.ts +++ b/apps/www/data/Footer.ts @@ -1,4 +1,9 @@ -import { skillBasedSolutions, useCaseSolutions } from 'data/Solutions' +import { + appTypeSolutions, + migrationSolutions, + skillBasedSolutions, + useCaseSolutions, +} from 'data/Solutions' import { PrivacySettings } from 'ui-patterns/PrivacySettings' const footerData = [ @@ -50,10 +55,6 @@ const footerData = [ { title: 'Solutions', links: [ - { - text: 'Hosted Postgres', - url: '/solutions/hosted-postgres', - }, ...skillBasedSolutions.solutions.map((solution) => ({ text: solution.text, url: solution.url, @@ -62,6 +63,14 @@ const footerData = [ text: solution.text, url: solution.url, })), + ...appTypeSolutions.solutions.map((solution) => ({ + text: solution.text, + url: solution.url, + })), + ...migrationSolutions.solutions.map((solution) => ({ + text: solution.text, + url: solution.url, + })), ], }, { diff --git a/apps/www/data/solutions/hosted-postgres.tsx b/apps/www/data/solutions/hosted-postgres.tsx index 1c2d1d338df..4a6798134f4 100644 --- a/apps/www/data/solutions/hosted-postgres.tsx +++ b/apps/www/data/solutions/hosted-postgres.tsx @@ -433,7 +433,18 @@ const data: () => { id: 'multigres', title: 'Multigres is coming', description: ( - <>Learn more about Multigres and the performance benefits you'll get when it ships. + <> + Learn more about{' '} + + Multigres + {' '} + and the performance benefits you'll get when it ships. + ), icon: Sparkles, }, From 9fc8109067265322b3dde55c963a9eb7523a1a99 Mon Sep 17 00:00:00 2001 From: Gildas Garcia <1122076+djhi@users.noreply.github.com> Date: Wed, 10 Jun 2026 11:56:12 +0200 Subject: [PATCH 065/134] chore: update CI e2e tests diagnostics (#46607) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problem We often get errors while starting the local supabase instance on CI. We added diagnostics but they are targeting the wrong port. ## Solution Fix the diagnostics logs ## Summary by CodeRabbit * **Chores** * Granted additional CI credentials and added cloud role assumption plus container registry login before running self‑hosted end-to-end tests. * Improved workflow diagnostics to check an alternate local database port (54322) and show clearer messages when the service is not listening. --- .github/workflows/studio-e2e-test.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/studio-e2e-test.yml b/.github/workflows/studio-e2e-test.yml index 8c5a2992c9d..46e85ec2ae3 100644 --- a/.github/workflows/studio-e2e-test.yml +++ b/.github/workflows/studio-e2e-test.yml @@ -24,7 +24,6 @@ jobs: permissions: contents: write - env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} @@ -87,7 +86,7 @@ jobs: - name: Pre-start diagnostics run: | docker ps -a - sudo ss -tlnp | grep 5432 || echo "5432 free" + sudo ss -tlnp | grep 54322 || echo "54322 free" - name: Start supabase if: steps.filter.outputs.studio == 'true' @@ -97,7 +96,7 @@ jobs: if: failure() run: | docker ps -a - sudo ss -tlnp | grep 5432 + sudo ss -tlnp | grep 54322 || echo "54322 not listening" docker logs $(docker ps -aq) 2>&1 || true - name: Build studio From fe1ecf31af98074a60a52913273923d73a364d74 Mon Sep 17 00:00:00 2001 From: Alexander Alexandrov Date: Wed, 10 Jun 2026 13:34:43 +0300 Subject: [PATCH 066/134] Add myself to `humans.txt` (#46776) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Docs update. ## What is the current behavior? The `humans.txt` file is incomplete. ## What is the new behavior? I added myself to `humans.txt`. ## Additional context Add any other context or screenshots. ## Summary by CodeRabbit * **Chores** * Updated team roster. --- apps/docs/public/humans.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/docs/public/humans.txt b/apps/docs/public/humans.txt index 539b9138c86..c05c48fd0fb 100644 --- a/apps/docs/public/humans.txt +++ b/apps/docs/public/humans.txt @@ -12,6 +12,7 @@ Alaister Young Aleksi Immonen Alex Hall Alex Hsu +Alexander Alexandrov Alexander Korotkov Ali Waseem Allan S From 2191669d08679d7c6580664115eac092a8cbddb6 Mon Sep 17 00:00:00 2001 From: Mert YEREKAPAN <33198490+myerekapan@users.noreply.github.com> Date: Wed, 10 Jun 2026 13:20:27 +0200 Subject: [PATCH 067/134] feat(studio): add upgrade CTA placement experiment (#45858) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Replaces the header upgrade CTA (PR #44494, which design team wanted to iterate on) with a placement experiment that tests three non-chrome surfaces for the free-plan "Upgrade to Pro" CTA. PostHog flag `upgradeCtaPlacement` (free-plan users only) with four arms: | Variant | Surface | | --- | --- | | `control` | No CTA (baseline cohort, still tracked) | | `user_dropdown` | Full-width button pinned in the account dropdown | | `org_projects_list` | Project-card-shaped usage tile, first card in the org project grid | ## Details ### `user_dropdown` - Full-width `Upgrade to Pro` button in `UserDropdown`, gated to org-scoped routes only (`/project/*`, `/org/*`) so the org-billing CTA never shows on `/account`, `/organizations`, etc. — addresses the scope concern raised in review. - Dropdown uses controlled `open` state so it closes before navigation (it lives in the global layout, so a route change alone wouldn't dismiss the overlay). ### `org_projects_list` - `PlanUsageCard` renders as the first `
  • ` in the project grid (via `ProjectList`'s `prependCard`), matching `ProjectCard` shape so it reads like another project tile. Also renders during the project-list loading state to avoid pop-in. Arc 2026-06-08 20 02 54 ### Shared card styling - Metric rows (Egress, Database size, Monthly active users, File storage) show `current / limit` with a progress ring; ring/value turn warning at ≥80% and over at ≥100%. - Rows are clickable deep-links to `/org/[slug]/usage#` with a hover chevron and dashed separators; the same row component is used by both the embedded and project-card variants. - Skeleton placeholder renders from first paint so the card reserves layout while `useOrgUsageQuery` resolves. - Exposure is fired optimistically while the org query loads (skeleton shows immediately), but the experiment exposure event only fires once free-plan is confirmed. ### Telemetry - `upgrade_cta_clicked` with `placement: user_dropdown | home_usage_card | org_projects_list`. - `upgrade_cta_placement_experiment_exposed` with `variant` — the custom exposure event (snake_case experiment id `upgrade_cta_placement`; the flag key stays camelCase `upgradeCtaPlacement`). ### Header CTA sunset - `HeaderUpgradeButton` and its wiring in `LayoutHeader` / `MobileNavigationBar` removed (master's #46144 already removed the button; this branch drops the remaining `header_upgrade_cta_clicked` event). ## Before merging - [x] Create the `upgradeCtaPlacement` flag + experiment in PostHog (4 variants, free-plan targeting, custom exposure event `upgrade_cta_placement_experiment_exposed`). - [x] Archive the now-orphaned `headerUpgradeCta` flag. ## Test plan - [x] Override the flag per variant via the dev toolbar on staging; confirm each surface renders and `upgrade_cta_clicked` fires with the right `placement`. - [x] `control` shows no CTA but still emits the exposure event. - [x] Paid-plan org and self-hosted (`IS_PLATFORM=false`) show nothing. - [x] Clicking a metric row deep-links to the matching usage section; clicking Upgrade routes to billing. ## Summary by CodeRabbit * **New Features** * Experimentally surface an “Upgrade to Pro” CTA in the user dropdown and on the projects page for eligible free-plan orgs. * Added a Plan Usage card showing free-plan metrics and upgrade prompts on the organization projects page; hides when irrelevant or errored. * Project list and its loading view support inserting a custom/prepend card in card mode. * **Telemetry** * Added tracking for CTA clicks and experiment exposure; placement is persisted per org. --------- Co-authored-by: kemal --- .../Home/ProjectList/EmptyStates.tsx | 4 +- .../Home/ProjectList/ProjectList.tsx | 25 +- .../interfaces/ProjectHome/PlanUsageCard.tsx | 252 ++++++++++++++++++ .../components/interfaces/UserDropdown.tsx | 30 +++ .../hooks/misc/useUpgradeCtaExperiment.ts | 97 +++++++ apps/studio/pages/org/[slug]/index.tsx | 19 +- packages/common/telemetry-constants.ts | 36 +++ 7 files changed, 454 insertions(+), 9 deletions(-) create mode 100644 apps/studio/components/interfaces/ProjectHome/PlanUsageCard.tsx create mode 100644 apps/studio/hooks/misc/useUpgradeCtaExperiment.ts diff --git a/apps/studio/components/interfaces/Home/ProjectList/EmptyStates.tsx b/apps/studio/components/interfaces/Home/ProjectList/EmptyStates.tsx index 77f982a5612..4c4aa6a94a0 100644 --- a/apps/studio/components/interfaces/Home/ProjectList/EmptyStates.tsx +++ b/apps/studio/components/interfaces/Home/ProjectList/EmptyStates.tsx @@ -1,6 +1,7 @@ import { BoxPlus } from 'icons' import { Plus } from 'lucide-react' import Link from 'next/link' +import { ReactNode } from 'react' import { Button, Card, @@ -65,9 +66,10 @@ export const LoadingTableView = () => { ) } -export const LoadingCardView = () => { +export const LoadingCardView = ({ prependCard }: { prependCard?: ReactNode }) => { return (
      + {prependCard}
    diff --git a/apps/studio/components/interfaces/Home/ProjectList/ProjectList.tsx b/apps/studio/components/interfaces/Home/ProjectList/ProjectList.tsx index ed387e578bc..be8d7986a29 100644 --- a/apps/studio/components/interfaces/Home/ProjectList/ProjectList.tsx +++ b/apps/studio/components/interfaces/Home/ProjectList/ProjectList.tsx @@ -2,7 +2,7 @@ import { keepPreviousData } from '@tanstack/react-query' import { useDebounce } from '@uidotdev/usehooks' import { LOCAL_STORAGE_KEYS, useParams } from 'common' import { parseAsArrayOf, parseAsString, parseAsStringLiteral, useQueryState } from 'nuqs' -import { useMemo } from 'react' +import { ReactNode, useMemo } from 'react' import { Card, cn, @@ -40,9 +40,19 @@ import type { Organization } from '@/types' export interface ProjectListProps { organization?: Organization rewriteHref?: (projectRef: string) => string + /** + * Optional content rendered as the first `
  • ` inside the grid view, before the + * project cards. Used by the upgrade CTA placement experiment to slot a card-shaped + * usage tile in the project list. Ignored in table view. + */ + prependCard?: ReactNode } -export const ProjectList = ({ organization: organization_, rewriteHref }: ProjectListProps) => { +export const ProjectList = ({ + organization: organization_, + rewriteHref, + prependCard, +}: ProjectListProps) => { const { slug: urlSlug } = useParams() const { data: selectedOrganization } = useSelectedOrganizationQuery() @@ -150,7 +160,11 @@ export const ProjectList = ({ organization: organization_, rewriteHref }: Projec } if (isLoadingPermissions || isLoadingProjects || !organization) { - return viewMode === 'table' ? : + return viewMode === 'table' ? ( + + ) : ( + + ) } if (isEmpty) { @@ -159,7 +173,7 @@ export const ProjectList = ({ organization: organization_, rewriteHref }: Projec if (viewMode === 'table') { return ( - + {/* [Joshen] Ideally we can figure out sticky table headers here */} @@ -277,7 +291,7 @@ export const ProjectList = ({ organization: organization_, rewriteHref }: Projec ) : noResultsFromSearch ? ( ) : ( -
    +
      + {prependCard} {orgProjects?.map((project) => ( { + if (value === 0) return '0 GB' + if (value < 1) return `${(value * 1000).toFixed(0)} MB` + return `${value.toFixed(value < 10 ? 2 : 1)} GB` +} + +const formatGigabyteLimit = (limit: number) => { + if (limit < 1) return `${(limit * 1000).toFixed(0)} MB` + return `${limit} GB` +} + +const formatCount = (value: number) => { + if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}M` + if (value >= 1_000) return `${(value / 1_000).toFixed(1)}k` + return value.toLocaleString() +} + +const formatCountLimit = (limit: number) => { + if (limit >= 1_000_000) return `${(limit / 1_000_000).toFixed(0)}M` + if (limit >= 1_000) return `${(limit / 1_000).toFixed(0)}k` + return limit.toLocaleString() +} + +const formatValue = (value: number, unit: MetricUnit) => + unit === 'gigabytes' ? formatGigabytes(value) : formatCount(value) + +const formatLimit = (limit: number, unit: MetricUnit) => + unit === 'gigabytes' ? formatGigabyteLimit(limit) : formatCountLimit(limit) + +const RING_RADIUS = 7 +const RING_CIRCUMFERENCE = 2 * Math.PI * RING_RADIUS + +const ProgressRing = ({ + ratio, + isOver, + isApproaching, +}: { + ratio: number + isOver: boolean + isApproaching: boolean +}) => { + const clamped = Math.max(0, Math.min(1, ratio)) + const offset = RING_CIRCUMFERENCE * (1 - clamped) + return ( + + ) +} + +// The upgrade CTA placement experiment variant this card represents. Used as the telemetry +// `source` + `placement` value. Kept as a constant so the tracking stays explicit. +const PLACEMENT = 'org_projects_list' + +const CompactMetricRow = ({ + usageItem, + config, + orgSlug, +}: { + usageItem: OrgMetricsUsage + config: MetricConfig + orgSlug: string +}) => { + const current = usageItem.usage ?? 0 + const limit = usageItem.pricing_free_units ?? 0 + const ratio = limit > 0 ? current / limit : 0 + const isOver = limit > 0 && current >= limit + const isApproaching = limit > 0 && ratio >= 0.8 && !isOver + + return ( + +
      +
      + + + {config.label} + +
      +
      + + + {formatValue(current, config.unit)} + + / + {formatLimit(limit, config.unit)} + + +
      +
      + + ) +} + +const SkeletonMetricRow = ({ label }: { label: string }) => ( +
      +
      +
      +
      + {label} +
      +
      +
      +
      +) + +/** + * Renders the upgrade CTA's plan-usage card as the first tile in the org project list + * (the `org_projects_list` experiment variant). The parent is responsible for gating on + * the experiment variant + free plan — this component only renders the visual sections + * once usage data is available. Shaped like a `ProjectCard` so it reads as another tile. + */ +export const PlanUsageCard = () => { + const track = useTrack() + const { data: organization } = useSelectedOrganizationQuery() + const { data: usage, isSuccess, isError } = useOrgUsageQuery({ orgSlug: organization?.slug }) + + const visibleRows = isSuccess + ? METRICS.map((config) => { + const usageItem = usage.usages.find((u) => u.metric === config.key) + if (!usageItem) return null + if (!usageItem.available_in_plan) return null + if (!usageItem.pricing_free_units || usageItem.pricing_free_units <= 0) return null + return { config, usageItem } + }).filter((row): row is { config: MetricConfig; usageItem: OrgMetricsUsage } => row !== null) + : [] + + // Hide entirely on hard error or when the org has zero applicable metrics — both + // are extreme edge cases. Otherwise always render the card shell so the layout is + // reserved from first paint and the usage rows fade in once the query resolves. + if (isError) return null + if (isSuccess && visibleRows.length === 0) return null + + return ( +
    • +
      +
      +
      +
      Free plan usage
      +

      Current billing cycle

      +
      +
      + track('upgrade_cta_clicked', { placement: PLACEMENT })} + /> +
      +
      +
      + {isSuccess + ? visibleRows.map(({ config, usageItem }) => ( + + )) + : METRICS.map((config) => )} +
      +
      +
    • + ) +} diff --git a/apps/studio/components/interfaces/UserDropdown.tsx b/apps/studio/components/interfaces/UserDropdown.tsx index d31d90dec39..b4f64927828 100644 --- a/apps/studio/components/interfaces/UserDropdown.tsx +++ b/apps/studio/components/interfaces/UserDropdown.tsx @@ -3,6 +3,7 @@ import { FlaskConical, Loader2, ScrollText, Settings } from 'lucide-react' import { useTheme } from 'next-themes' import Link from 'next/link' import { useRouter } from 'next/router' +import { useState } from 'react' import { cn, DropdownMenu, @@ -22,7 +23,9 @@ import { ButtonTooltip } from '../ui/ButtonTooltip' import { useFeaturePreviewModal } from './App/FeaturePreview/FeaturePreviewContext' import { TimezoneDropdown } from './UserDropdown/TimezoneDropdown' import { ProfileImage } from '@/components/ui/ProfileImage' +import { UpgradePlanButton } from '@/components/ui/UpgradePlanButton' import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' +import { useUpgradeCtaExperiment } from '@/hooks/misc/useUpgradeCtaExperiment' import { IS_PLATFORM } from '@/lib/constants' import { useProfileNameAndPicture } from '@/lib/profile' import { useTrack } from '@/lib/telemetry/track' @@ -45,9 +48,20 @@ export function UserDropdown({ const { toggleFeaturePreviewModal } = useFeaturePreviewModal() const track = useTrack() + const { variant: upgradeCtaVariant } = useUpgradeCtaExperiment() + // Per Slack feedback (Jonny): the upgrade CTA is org-scoped, so only show it on routes + // where an org is in scope. Excludes /account/*, /organizations, /new, marketing routes, etc. + const isOrgScopedRoute = + router.pathname.startsWith('/project/') || router.pathname.startsWith('/org/') + const showUpgradeCta = upgradeCtaVariant === 'user_dropdown' && isOrgScopedRoute + + const [isOpen, setIsOpen] = useState(false) + return ( { + setIsOpen(open) if (open) track('header_user_dropdown_opened') }} > @@ -155,6 +169,22 @@ export function UserDropdown({ )} + {showUpgradeCta && ( + <> + +
      + { + track('upgrade_cta_clicked', { placement: 'user_dropdown' }) + setIsOpen(false) + }} + /> +
      + + )} {IS_PLATFORM && ( <> diff --git a/apps/studio/hooks/misc/useUpgradeCtaExperiment.ts b/apps/studio/hooks/misc/useUpgradeCtaExperiment.ts new file mode 100644 index 00000000000..23ba7f53d9d --- /dev/null +++ b/apps/studio/hooks/misc/useUpgradeCtaExperiment.ts @@ -0,0 +1,97 @@ +import { IS_PLATFORM, safeLocalStorage, useFeatureFlags, useParams } from 'common' +import { useEffect, useMemo } from 'react' + +import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' +import { useTrackExperimentExposure } from '@/hooks/misc/useTrackExperimentExposure' +import { usePHFlag } from '@/hooks/ui/useFlag' + +// PostHog flag key (camelCase, matches other flag naming in the codebase). +export const UPGRADE_CTA_FLAG_NAME = 'upgradeCtaPlacement' + +// snake_case experiment ID so the auto-fired exposure event name matches the +// `[experiment_id]_experiment_exposed` typed event registered in telemetry-constants.ts. +const UPGRADE_CTA_EXPERIMENT_ID = 'upgrade_cta_placement' + +// localStorage key prefix for the seeded variant (see hook docs). Keyed per org slug +// because eligibility folds in that org's plan. +const UPGRADE_CTA_SEED_PREFIX = 'supabase-upgrade-cta-variant-' + +export type UpgradeCtaPlacement = 'control' | 'user_dropdown' | 'org_projects_list' + +const VALID_VARIANTS: UpgradeCtaPlacement[] = ['control', 'user_dropdown', 'org_projects_list'] + +/** + * Shared experiment state for the upgrade CTA placement test. + * + * `variant` is the placement to render, and is gated on a confirmed free plan + the + * experiment flag — paid users never receive a variant, so the CTA never renders for them. + * + * First-paint correctness: PostHog flags are fetched async on every load, so the flag + * (and therefore the variant) is unknown at first paint. To avoid the CTA popping in + * (layout shift) or flashing, we persist the last resolved variant per org and seed from + * it synchronously. The seed is used only until the live flag + plan resolve, then the + * live value takes over and is re-persisted — so it self-heals if anything changed. A + * confirmed paid plan always wins over a stale seed, so the CTA can't flash for paid users. + * + * Net effect: correct at first paint with no shift/flash on every visit after the first + * (the first-ever visit to a given org still resolves async). + * + * Exposure tracking fires only once confirmed (free-plan + in experiment), so the + * experiment cohort stays accurate. + */ +export const useUpgradeCtaExperiment = () => { + const { slug } = useParams() + const { data: organization, isPending: isOrgPending } = useSelectedOrganizationQuery() + const flagStore = useFeatureFlags() + const flagValue = usePHFlag(UPGRADE_CTA_FLAG_NAME) + + const flagsLoaded = flagStore.hasLoaded === true + const planKnown = !isOrgPending + const isFreePlan = organization?.plan?.id === 'free' + const isInExperiment = + typeof flagValue === 'string' && VALID_VARIANTS.includes(flagValue as UpgradeCtaPlacement) + + // The definitive variant for a confirmed free-plan user in the experiment. + const liveVariant = isFreePlan && isInExperiment ? (flagValue as UpgradeCtaPlacement) : undefined + + // Synchronous seed from the last resolved variant for this org. Read via useMemo so it + // re-reads when the org slug changes (e.g. navigating between orgs without a remount). + const seedKey = `${UPGRADE_CTA_SEED_PREFIX}${slug ?? 'none'}` + const seededVariant = useMemo(() => { + const item = safeLocalStorage.getItem(seedKey) + if (!item) return null + try { + const parsed = JSON.parse(item) + return VALID_VARIANTS.includes(parsed) ? (parsed as UpgradeCtaPlacement) : null + } catch { + return null + } + }, [seedKey]) + + let variant: UpgradeCtaPlacement | undefined + if (!IS_PLATFORM) { + // No billing/plans on self-hosted, so there is nothing to upgrade to — never show. + variant = undefined + } else if (flagsLoaded && planKnown) { + // Fully resolved — source of truth. + variant = liveVariant + } else if (planKnown && !isFreePlan) { + // Confirmed paid — never show, even if a stale seed says otherwise. + variant = undefined + } else { + // Free, or still loading — trust the last known value to avoid a first-paint shift. + variant = seededVariant ?? undefined + } + + // Persist the last resolved variant once we have a definitive answer, so the next visit + // to this org can seed from it. Only matters before the live value resolves, so we don't + // need it in component state. + useEffect(() => { + if (!IS_PLATFORM || !flagsLoaded || !planKnown) return + safeLocalStorage.setItem(seedKey, JSON.stringify(liveVariant ?? null)) + }, [flagsLoaded, planKnown, liveVariant, seedKey]) + + useTrackExperimentExposure(UPGRADE_CTA_EXPERIMENT_ID, liveVariant) + + return { isFreePlan, variant } +} diff --git a/apps/studio/pages/org/[slug]/index.tsx b/apps/studio/pages/org/[slug]/index.tsx index 25348beed3b..07955393c69 100644 --- a/apps/studio/pages/org/[slug]/index.tsx +++ b/apps/studio/pages/org/[slug]/index.tsx @@ -5,18 +5,22 @@ import { Admonition } from 'ui-patterns' import { ProjectList } from '@/components/interfaces/Home/ProjectList/ProjectList' import { HomePageActions } from '@/components/interfaces/HomePageActions' +import { PlanUsageCard } from '@/components/interfaces/ProjectHome/PlanUsageCard' import DefaultLayout from '@/components/layouts/DefaultLayout' import OrganizationLayout from '@/components/layouts/OrganizationLayout' import { PageLayout } from '@/components/layouts/PageLayout/PageLayout' import { ScaffoldContainer, ScaffoldSection } from '@/components/layouts/Scaffold' import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' +import { useUpgradeCtaExperiment } from '@/hooks/misc/useUpgradeCtaExperiment' import type { NextPageWithLayout } from '@/types' const ProjectsPage: NextPageWithLayout = () => { const isUserMFAEnabled = useIsMFAEnabled() const { data: org } = useSelectedOrganizationQuery() + const { variant: upgradeCtaVariant } = useUpgradeCtaExperiment() const disableAccessMfa = org?.organization_requires_mfa && !isUserMFAEnabled + const showOrgProjectsListUsageCard = upgradeCtaVariant === 'org_projects_list' return ( @@ -39,9 +43,18 @@ const ProjectsPage: NextPageWithLayout = () => { } /> ) : ( -
      - - +
      +
      + + +
      + {showOrgProjectsListUsageCard && ( + + )}
      )} diff --git a/packages/common/telemetry-constants.ts b/packages/common/telemetry-constants.ts index d000c1e47ee..f90428deb79 100644 --- a/packages/common/telemetry-constants.ts +++ b/packages/common/telemetry-constants.ts @@ -3111,6 +3111,40 @@ export interface AccessTokenRemovedEvent { groups: Omit } +/** + * User clicked the "Upgrade to Pro" CTA in one of the experiment placement surfaces. + * GROWTH experiment: `upgradeCtaPlacement` (user_dropdown / org_projects_list). + * + * @group Events + * @source studio + */ +export interface UpgradeCtaClickedEvent { + action: 'upgrade_cta_clicked' + properties: { + placement: 'user_dropdown' | 'org_projects_list' + } + groups: Omit +} + +/** + * User was exposed to the upgrade CTA placement experiment. + * Fires once per session per free-plan user enrolled in any variant (including control), + * so the conversion analysis has a baseline cohort. + * + * @group Events + * @source studio + */ +export interface UpgradeCtaPlacementExperimentExposedEvent { + action: 'upgrade_cta_placement_experiment_exposed' + properties: { + /** + * The experiment variant shown to the user + */ + variant: 'control' | 'user_dropdown' | 'org_projects_list' + } + groups: Omit +} + /** * User clicked the primary CTA on a resource exhaustion warning banner. * @@ -3520,6 +3554,8 @@ export type TelemetryEvent = | ComputeBadgeUpgradeClickedEvent | FreeMicroUpgradeBannerDismissedEvent | FreeMicroUpgradeBannerCtaClickedEvent + | UpgradeCtaClickedEvent + | UpgradeCtaPlacementExperimentExposedEvent | AccessTokenCreatedEvent | AccessTokenRemovedEvent | ResourceExhaustionBannerUpgradeClickedEvent From 948ee734ef64b18cc0c0054cbfb7842b866324f4 Mon Sep 17 00:00:00 2001 From: Jordi Enric <37541088+jordienr@users.noreply.github.com> Date: Wed, 10 Jun 2026 14:14:39 +0200 Subject: [PATCH 068/134] fix(reports): show absolute CPU usage instead of normalized stack DEBUG-135 (#46781) ## Problem The CPU usage chart rendered every bar as nearly full (looked like ~100% CPU) even when actual usage was 0.13%. The header value and tooltip were correct (0.13%); only the bars were wrong. ## Cause The chart used `normalizeVisibleStackToPercent: true`, which rescales the visible stacked series so they always sum to 100% of the bar height. The CPU series are already absolute percentages, so normalizing stretched a real 0.13% to fill the whole bar. The `Idle` series existed only to pad the stack to 100%. ## Fix - Remove `normalizeVisibleStackToPercent` from the CPU chart so series render at absolute values against the fixed 0-100% Y axis. - Drop the `Idle` series (no longer needed to pad the stack, and we don't want to show it). - Revert the unused `hideFromLegend` plumbing from the earlier attempt. Result: low CPU usage now renders as a near-empty bar, accurately reflecting the real value. ## Summary by CodeRabbit * **Bug Fixes** * Updated CPU usage chart in database reports to display a focused set of CPU metrics. --------- Co-authored-by: Claude Opus 4.7 --- apps/studio/data/reports/database-charts.ts | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/apps/studio/data/reports/database-charts.ts b/apps/studio/data/reports/database-charts.ts index f6ea44013a3..4ce335f98d4 100644 --- a/apps/studio/data/reports/database-charts.ts +++ b/apps/studio/data/reports/database-charts.ts @@ -171,7 +171,6 @@ export const getReportAttributesV2: ( showLegend: true, showMaxValue: false, showGrid: true, - normalizeVisibleStackToPercent: true, YAxisProps: { width: 55, domain: [0, 100] as [number, number], @@ -230,24 +229,6 @@ export const getReportAttributesV2: ( tooltip: 'CPU time spent on other tasks (e.g., background processes, software interrupts)', }, - { - attribute: 'cpu_usage_busy_idle', - provider: 'infra-monitoring', - label: 'Idle', - format: '%', - omitFromTotal: true, - color: { light: '#6EA85F', dark: '#A3FFC2' }, - fill: { light: '#A6D8AE', dark: '#2A5C3F' }, - tooltip: 'CPU time spent idle and available for new work', - }, - { - attribute: 'cpu_usage_max', - provider: 'reference-line', - label: 'Max', - value: 100, - tooltip: 'Max CPU usage', - isMaxValue: true, - }, ], }, { From 691a6e67190fd3025e2c65a613184b117b39a290 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Wed, 10 Jun 2026 14:53:46 +0200 Subject: [PATCH 069/134] docs: Relink read-only mode in disk size doc (#46805) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## Summary by CodeRabbit * **Documentation** * Updated the database size guide to link read-only mode management instructions to the correct documentation section for improved navigation. --- apps/docs/content/guides/platform/database-size.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/content/guides/platform/database-size.mdx b/apps/docs/content/guides/platform/database-size.mdx index 9af02dff399..f2e63601fb7 100644 --- a/apps/docs/content/guides/platform/database-size.mdx +++ b/apps/docs/content/guides/platform/database-size.mdx @@ -26,7 +26,7 @@ Database size is consumed primarily by your data, indexes, and materialized view -Depending on your billing plan, your database can go into read-only mode which can prevent you inserting and deleting data. There are instructions for managing read-only mode in the [Disk Management](#disk-management) section. +Depending on your billing plan, your database can go into read-only mode which can prevent you inserting and deleting data. There are instructions for managing read-only mode in the [Read-Only Mode](#read-only-mode) section. From 3ca6f665bc486ccfc6a72033f0d10fc7f9cc254a Mon Sep 17 00:00:00 2001 From: Jordi Enric <37541088+jordienr@users.noreply.github.com> Date: Wed, 10 Jun 2026 16:59:56 +0200 Subject: [PATCH 070/134] feat(reports): add swap usage series to memory chart DEBUG-127 (#46780) ## Problem The Memory usage chart in the database report showed RAM used, cache, free, and total, but did not include swap. Swap activity is a meaningful signal of memory pressure and was only visible in a hidden standalone chart. ## Fix Added `swap_usage` (from the `infra-monitoring` provider) as an additional series in the `ram-usage` Memory chart. The series uses `omitFromTotal: true` so it does not inflate the stacked total, and carries the same tooltip text as the hidden standalone swap chart. The standalone `swap-usage` chart remains hidden as before. ## How to test - Open the database report for a project on any compute size. - Navigate to the Memory usage chart. - Confirm a "Swap" series appears in the legend and renders data alongside Used, Cache + Buffers, and Free. - Hover a data point and confirm the tooltip shows a Swap value with the memory-pressure description. - Confirm the Swap value does not contribute to the stacked total. ## Summary by CodeRabbit * **New Features** * Added a "Swap" metric to the RAM usage chart in reports, displaying swap memory usage information with an updated tooltip. --------- Co-authored-by: Claude Sonnet 4.6 --- apps/studio/data/reports/database-charts.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/studio/data/reports/database-charts.ts b/apps/studio/data/reports/database-charts.ts index 4ce335f98d4..9618ff3f69f 100644 --- a/apps/studio/data/reports/database-charts.ts +++ b/apps/studio/data/reports/database-charts.ts @@ -92,6 +92,14 @@ export const getReportAttributesV2: ( omitFromTotal: true, tooltip: 'Total RAM available on this instance', }, + { + attribute: 'ram_usage_swap', + provider: 'infra-monitoring', + label: 'Swap', + omitFromTotal: true, + tooltip: + 'Swap space in use by the operating system. Sustained swap usage indicates memory pressure and may degrade database performance', + }, ], }, { From a035fca40bd09472806ba50758d4cbd92d6b191a Mon Sep 17 00:00:00 2001 From: "supabase-supabase-autofixer[bot]" <248690971+supabase-supabase-autofixer[bot]@users.noreply.github.com> Date: Wed, 10 Jun 2026 17:09:59 +0200 Subject: [PATCH 071/134] [bot] Sync from supabase/troubleshooting (#46799) This PR syncs the latest troubleshooting guides from the supabase/troubleshooting repository. Co-authored-by: github-docs-bot --- ...r-component-verification-failed-94a76b.mdx | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 apps/docs/content/troubleshooting/FWD-wrappers-error-component-verification-failed-94a76b.mdx diff --git a/apps/docs/content/troubleshooting/FWD-wrappers-error-component-verification-failed-94a76b.mdx b/apps/docs/content/troubleshooting/FWD-wrappers-error-component-verification-failed-94a76b.mdx new file mode 100644 index 00000000000..3e066c4be35 --- /dev/null +++ b/apps/docs/content/troubleshooting/FWD-wrappers-error-component-verification-failed-94a76b.mdx @@ -0,0 +1,40 @@ +--- +title = "FDW Wrappers error: 'component verification failed'" +date_created = "2026-06-09T16:04:36+00:00" +topics = [ "platform" ] +keywords = [] +[[errors]] +code = "HV000" +message = "guest fdw error: component verification failed" + +--- + +If you are observing an `ERROR: HV000: guest fdw error: component verification failed` when querying a wrapper foreign tables, it indicates that the configured Wasm package metadata does not match the downloaded component. As a security measure, the Wrappers extension blocks the module when this mismatch occurs. + +To resolve this, update your foreign server configuration to use the correct package version and checksum. Details depend on the exact Wrapper and can be found here: https://fdw.dev/catalog/wasm/ + +**How to fix the configuration:** +Run the following SQL via the [SQL Editor](/dashboard/project/_/sql/new): + +```sql +ALTER SERVER example_server OPTIONS ( + SET fdw_package_url '[THE_CORRECT_URL]', + SET fdw_package_version '[THE_CORRECT_VERSION]', + SET fdw_package_checksum '[INTERNAL_ID]' +); +``` + +**Verify the update:** +You can confirm the update by inspecting the server options: + +```sql +select srvname, unnest(srvoptions) as option +from pg_foreign_server +where srvname = 'example_server'; +``` + +Test the connection by querying your foreign table: + +```sql +select * from example_table limit 1; +``` From 9b438d3f8db7bc62d73e07070a2b46a2d82bc023 Mon Sep 17 00:00:00 2001 From: Jeremias Menichelli Date: Wed, 10 Jun 2026 18:14:27 +0200 Subject: [PATCH 072/134] fix: Add /docs to Link hrefs on markdown script (#46798) --- .../internals/generate-guides-markdown.ts | 4 +- apps/docs/internals/internal-links.test.ts | 49 ++++++++++++++++++- apps/docs/internals/internal-links.ts | 18 +++++++ 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/apps/docs/internals/generate-guides-markdown.ts b/apps/docs/internals/generate-guides-markdown.ts index a7be3589be5..6758ba073ac 100644 --- a/apps/docs/internals/generate-guides-markdown.ts +++ b/apps/docs/internals/generate-guides-markdown.ts @@ -3,7 +3,7 @@ import path from 'node:path' import { globby } from 'globby' import matter from 'gray-matter' -import { getInternalLinkBaseUrl, prefixInternalLinks } from './internal-links' +import { getInternalLinkBaseUrl, prefixInternalLinks, withDocsBasePath } from './internal-links' const PARTIALS_DIR = path.join(process.cwd(), 'content', '_partials') @@ -109,7 +109,7 @@ function convertLinkPanels(content: string): string { return content.replace(/([\s\S]*?)<\/Link>/g, (full, linkAttrs, body) => { const hrefMatch = linkAttrs.match(/\bhref="([^"]+)"/) if (!hrefMatch) return full - const href = hrefMatch[1] + const href = withDocsBasePath(hrefMatch[1]) const panelOpen = body.match(/<(GlassPanel|IconPanel)\b/) if (!panelOpen) return full diff --git a/apps/docs/internals/internal-links.test.ts b/apps/docs/internals/internal-links.test.ts index 4558e679f71..54a4bf783e5 100644 --- a/apps/docs/internals/internal-links.test.ts +++ b/apps/docs/internals/internal-links.test.ts @@ -1,6 +1,53 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import { getInternalLinkBaseUrl, prefixInternalLinks } from './internal-links' +import { getInternalLinkBaseUrl, prefixInternalLinks, withDocsBasePath } from './internal-links' + +describe('withDocsBasePath', () => { + it('prepends /docs to a root-relative href', () => { + expect(withDocsBasePath('/guides/self-hosting/docker')).toBe('/docs/guides/self-hosting/docker') + }) + + it('prepends /docs to a single-segment href', () => { + expect(withDocsBasePath('/contribute')).toBe('/docs/contribute') + }) + + it('leaves hrefs that already start with /docs/ alone', () => { + expect(withDocsBasePath('/docs/guides/foo')).toBe('/docs/guides/foo') + }) + + it('leaves the exact /docs href alone', () => { + expect(withDocsBasePath('/docs')).toBe('/docs') + }) + + it('does not match prefixes like /docsx that only share leading chars', () => { + expect(withDocsBasePath('/docsx/foo')).toBe('/docs/docsx/foo') + }) + + it('leaves absolute http(s) URLs alone', () => { + expect(withDocsBasePath('https://example.com/foo')).toBe('https://example.com/foo') + }) + + it('leaves protocol-relative URLs alone', () => { + expect(withDocsBasePath('//cdn.example.com/foo')).toBe('//cdn.example.com/foo') + }) + + it('leaves anchor-only hrefs alone', () => { + expect(withDocsBasePath('#section')).toBe('#section') + }) + + it('leaves mailto: hrefs alone', () => { + expect(withDocsBasePath('mailto:team@example.com')).toBe('mailto:team@example.com') + }) + + it('leaves relative ./ and ../ hrefs alone', () => { + expect(withDocsBasePath('./sibling')).toBe('./sibling') + expect(withDocsBasePath('../parent')).toBe('../parent') + }) + + it('preserves query strings and fragments', () => { + expect(withDocsBasePath('/guides/foo?x=1#bar')).toBe('/docs/guides/foo?x=1#bar') + }) +}) describe('getInternalLinkBaseUrl', () => { const ORIGINAL_ENV = process.env diff --git a/apps/docs/internals/internal-links.ts b/apps/docs/internals/internal-links.ts index 5742e007824..ae19af20595 100644 --- a/apps/docs/internals/internal-links.ts +++ b/apps/docs/internals/internal-links.ts @@ -1,3 +1,21 @@ +const DOCS_BASE_PATH = process.env.NEXT_PUBLIC_BASE_PATH || '/docs' + +/** + * Prepend the docs basePath to a root-relative href, mirroring what Next.js + * `` does at render time. Used when extracting an `href` attribute out + * of MDX `` components into plain markdown — without this, links like + * `/guides/foo` lose the `/docs` prefix the deployed site adds. + * + * Returns the href unchanged when it's already prefixed, external, anchor- + * only, or relative (`./`, `../`). + */ +export function withDocsBasePath(href: string): string { + if (!href.startsWith('/')) return href + if (href.startsWith('//')) return href + if (href === DOCS_BASE_PATH || href.startsWith(`${DOCS_BASE_PATH}/`)) return href + return `${DOCS_BASE_PATH}${href}` +} + /** * Returns the absolute base URL to prepend to root-relative markdown links * (e.g. `/dashboard/...`). Empty when no rewrite should happen — typically From 22c02a13047a58ff3a91bc3dc402c42848119e96 Mon Sep 17 00:00:00 2001 From: "kemal.earth" <606977+kemaldotearth@users.noreply.github.com> Date: Wed, 10 Jun 2026 17:58:11 +0100 Subject: [PATCH 073/134] fix(studio): custom report tooltips overflow (#46772) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Previously the `overflow-hidden` on the custom report charts container was cutting off the tooltip within the card bounds. This PR introduces `PortalChartTooltip` here so the tooltip is able to appear outside of the bounding area. It is still directionally aware, just relative to the page viewport as opposed to bounding box. | Before | After | |--------|--------| | image | Screenshot 2026-06-09 at 11 45
38 | If you want to test quickly but have no data, you can ask Claude to generate you a dummy custom report chart and then move it around, test the long tooltips. ## Summary by CodeRabbit * **New Features** * Tooltips can now render in a dedicated layer to improve visibility and avoid clipping. * Option added to enable portal-rendered tooltips in condensed/snippet views. * **Bug Fixes** * Improved tooltip positioning to prevent overflow outside the viewport. * Corrected percentage label suffixes in chart tooltips. --- .../Reports/ReportBlock/ChartBlock.tsx | 13 ++-- .../Reports/ReportBlock/ReportBlock.tsx | 1 + .../ui/Charts/PortalChartTooltip.tsx | 67 +++++++++++++++++++ .../components/ui/QueryBlock/QueryBlock.tsx | 34 +++++++--- 4 files changed, 103 insertions(+), 12 deletions(-) create mode 100644 apps/studio/components/ui/Charts/PortalChartTooltip.tsx diff --git a/apps/studio/components/interfaces/Reports/ReportBlock/ChartBlock.tsx b/apps/studio/components/interfaces/Reports/ReportBlock/ChartBlock.tsx index eb3066e2ec3..63f1888a827 100644 --- a/apps/studio/components/interfaces/Reports/ReportBlock/ChartBlock.tsx +++ b/apps/studio/components/interfaces/Reports/ReportBlock/ChartBlock.tsx @@ -1,9 +1,9 @@ import dayjs from 'dayjs' import { Activity, BarChartIcon, Loader2 } from 'lucide-react' import { useRouter } from 'next/router' -import { ReactNode, useCallback, useEffect, useMemo, useState } from 'react' +import { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react' import { Bar, BarChart, CartesianGrid, Line, LineChart, XAxis, YAxis } from 'recharts' -import { ChartContainer, ChartTooltip, ChartTooltipContent, WarningIcon } from 'ui' +import { ChartContainer, ChartTooltip, WarningIcon } from 'ui' import { METRIC_THRESHOLDS } from './ReportBlock.constants' import { ReportBlockContainer } from './ReportBlockContainer' @@ -11,6 +11,7 @@ import { ChartConfig } from '@/components/interfaces/SQLEditor/UtilityPanel/Char import { ButtonTooltip } from '@/components/ui/ButtonTooltip' import { timestampFormatter } from '@/components/ui/Charts/Charts.utils' import NoDataPlaceholder from '@/components/ui/Charts/NoDataPlaceholder' +import { PortalChartTooltip } from '@/components/ui/Charts/PortalChartTooltip' import { checkHasNonPositiveValues, computeYAxisWidth, @@ -71,6 +72,7 @@ export const ChartBlock = ({ const { ref } = router.query const state = useDatabaseSelectorStateSnapshot() + const chartRef = useRef(null) const [chartStyle, setChartStyle] = useState(defaultChartStyle) const logScale = useMemo(() => defaultLogScale, [defaultLogScale]) const [latestValue, setLatestValue] = useState() @@ -298,6 +300,7 @@ export const ChartBlock = ({

      )} formatTooltipDate(x as string | number, 'DD MMM YYYY')} @@ -351,7 +355,8 @@ export const ChartBlock = ({ /> formatTooltipDate(x as string | number, 'DD MMM YYYY')} /> diff --git a/apps/studio/components/interfaces/Reports/ReportBlock/ReportBlock.tsx b/apps/studio/components/interfaces/Reports/ReportBlock/ReportBlock.tsx index a0740fee308..12c4ebc026d 100644 --- a/apps/studio/components/interfaces/Reports/ReportBlock/ReportBlock.tsx +++ b/apps/studio/components/interfaces/Reports/ReportBlock/ReportBlock.tsx @@ -149,6 +149,7 @@ export const ReportBlock = ({ {isSnippet ? ( , 'content'> & + Pick, 'active' | 'coordinate' | 'payload'> & { + chartRef: RefObject + } + +export const PortalChartTooltip = ({ chartRef, className, ...props }: PortalChartTooltipProps) => { + const { active, coordinate, payload } = props + const innerRef = useRef(null) + const [position, setPosition] = useState<{ left: number; top: number } | null>(null) + + useIsomorphicLayoutEffect(() => { + if (!active || typeof document === 'undefined') { + setPosition(null) + return + } + const el = innerRef.current + if (!el) return + + const containerRect = chartRef.current?.getBoundingClientRect() + const anchorX = (containerRect?.left ?? 0) + (coordinate?.x ?? 0) + const anchorY = (containerRect?.top ?? 0) + (coordinate?.y ?? 0) + + const { width, height } = el.getBoundingClientRect() + + let left = anchorX + TOOLTIP_OFFSET + if (left + width > window.innerWidth - VIEWPORT_MARGIN) { + left = anchorX - width - TOOLTIP_OFFSET + } + left = Math.max(VIEWPORT_MARGIN, Math.min(left, window.innerWidth - width - VIEWPORT_MARGIN)) + + const top = Math.max( + VIEWPORT_MARGIN, + Math.min(anchorY, window.innerHeight - height - VIEWPORT_MARGIN) + ) + + setPosition({ left, top }) + }, [active, coordinate?.x, coordinate?.y, payload, chartRef]) + + if (!active || typeof document === 'undefined') return null + + return createPortal( +
      + +
      , + document.body + ) +} diff --git a/apps/studio/components/ui/QueryBlock/QueryBlock.tsx b/apps/studio/components/ui/QueryBlock/QueryBlock.tsx index 2b4283a7522..50d18225885 100644 --- a/apps/studio/components/ui/QueryBlock/QueryBlock.tsx +++ b/apps/studio/components/ui/QueryBlock/QueryBlock.tsx @@ -8,6 +8,7 @@ import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader' import { ButtonTooltip } from '../ButtonTooltip' import { CHART_COLORS } from '../Charts/Charts.constants' +import { PortalChartTooltip } from '../Charts/PortalChartTooltip' import { SqlWarningAdmonition } from '../SqlWarningAdmonition' import { BlockViewConfiguration } from './BlockViewConfiguration' import { EditQueryButton } from './EditQueryButton' @@ -47,6 +48,8 @@ export interface QueryBlockProps { draggable?: boolean disabled?: boolean blockWriteQueries?: boolean + /** Render the chart tooltip in a portal so it isn't clipped by overflow-hidden ancestors (e.g. report cards). */ + portalTooltip?: boolean onExecute?: (queryType: 'select' | 'mutation') => void onRemoveChart?: () => void onUpdateChartConfig?: ({ chartConfig }: { chartConfig: Partial }) => void @@ -69,11 +72,13 @@ export const QueryBlock = ({ draggable = false, disabled = false, blockWriteQueries = false, + portalTooltip = false, onExecute, onRemoveChart, onUpdateChartConfig, onDragStart, }: QueryBlockProps) => { + const chartContainerRef = useRef(null) const [chartSettings, setChartSettings] = useState(chartConfig) const { xKey, yKey, view = 'table', logScale = false } = chartSettings @@ -280,6 +285,7 @@ export const QueryBlock = ({

      )} @@ -318,14 +324,26 @@ export const QueryBlock = ({ /> - xKeyDateFormat === 'date' - ? dayjs(value).format('MMM D YYYY HH:mm') - : String(value) - } - /> + portalTooltip ? ( + + xKeyDateFormat === 'date' + ? dayjs(value).format('MMM D YYYY HH:mm') + : String(value) + } + /> + ) : ( + + xKeyDateFormat === 'date' + ? dayjs(value).format('MMM D YYYY HH:mm') + : String(value) + } + /> + ) } /> From 6d0dc4544291f14f0350a1d6cc210ee8ac7e1a5b Mon Sep 17 00:00:00 2001 From: Francesco Sansalvadore Date: Wed, 10 Jun 2026 20:10:51 +0200 Subject: [PATCH 074/134] feat(www): legal hub (#46749) --- .../www/components/Legal/LegalDocVersions.tsx | 40 +-- .../components/Sections/PageBreadcrumb.tsx | 33 +++ apps/www/components/Sections/PageHeader.tsx | 31 +++ apps/www/data/Footer.ts | 4 + .../integration-partner-addendum/v1.mdx | 185 +++++++++++++ .../data/legal/partner-resources/mppa/v1.mdx | 243 ++++++++++++++++++ apps/www/pages/legal/index.tsx | 67 +++++ .../master-partner-program-agreement.tsx | 43 ++++ .../program-addenda/index.tsx | 66 +++++ .../integration-partner-addendum.tsx | 44 ++++ 10 files changed, 739 insertions(+), 17 deletions(-) create mode 100644 apps/www/components/Sections/PageBreadcrumb.tsx create mode 100644 apps/www/components/Sections/PageHeader.tsx create mode 100644 apps/www/data/legal/partner-resources/integration-partner-addendum/v1.mdx create mode 100644 apps/www/data/legal/partner-resources/mppa/v1.mdx create mode 100644 apps/www/pages/legal/index.tsx create mode 100644 apps/www/pages/legal/partner-resources/master-partner-program-agreement.tsx create mode 100644 apps/www/pages/legal/partner-resources/program-addenda/index.tsx create mode 100644 apps/www/pages/legal/partner-resources/program-addenda/integration-partner-addendum.tsx diff --git a/apps/www/components/Legal/LegalDocVersions.tsx b/apps/www/components/Legal/LegalDocVersions.tsx index 05a2655cabe..fa7d34f5615 100644 --- a/apps/www/components/Legal/LegalDocVersions.tsx +++ b/apps/www/components/Legal/LegalDocVersions.tsx @@ -45,23 +45,29 @@ const LegalDocVersions = ({ versions }: Props) => { return ( <> -
      - - -
      + {versions.length > 1 ? ( +
      + + +
      + ) : ( +

      + {versions[0].label} — {versions[0].effectiveDate} +

      + )} ) diff --git a/apps/www/components/Sections/PageBreadcrumb.tsx b/apps/www/components/Sections/PageBreadcrumb.tsx new file mode 100644 index 00000000000..b0c8b307123 --- /dev/null +++ b/apps/www/components/Sections/PageBreadcrumb.tsx @@ -0,0 +1,33 @@ +import Link from 'next/link' +import { Fragment } from 'react' + +interface BreadcrumbItem { + label: string + href?: string +} + +interface Props { + items: BreadcrumbItem[] +} + +const PageBreadcrumb = ({ items }: Props) => ( + +) + +export default PageBreadcrumb diff --git a/apps/www/components/Sections/PageHeader.tsx b/apps/www/components/Sections/PageHeader.tsx new file mode 100644 index 00000000000..f35f0b09d39 --- /dev/null +++ b/apps/www/components/Sections/PageHeader.tsx @@ -0,0 +1,31 @@ +import type { ReactNode } from 'react' +import { cn } from 'ui' + +import SectionContainer from '../Layouts/SectionContainer' + +interface Props { + breadcrumb?: ReactNode + title?: string + h1: ReactNode + subheader?: ReactNode + className?: string +} + +const PageHeader = ({ breadcrumb, title, h1, subheader, className }: Props) => ( +
      + + {breadcrumb &&
      {breadcrumb}
      } + {title && ( +

      {title}

      + )} +

      + {h1} +

      + {subheader && ( +

      {subheader}

      + )} +
      +
      +) + +export default PageHeader diff --git a/apps/www/data/Footer.ts b/apps/www/data/Footer.ts index f6839ecc8bd..75272add9c2 100644 --- a/apps/www/data/Footer.ts +++ b/apps/www/data/Footer.ts @@ -179,6 +179,10 @@ const footerData = [ text: 'General Availability', url: '/ga', }, + { + text: 'Legal', + url: '/legal', + }, { text: 'Terms of Service', url: '/terms', diff --git a/apps/www/data/legal/partner-resources/integration-partner-addendum/v1.mdx b/apps/www/data/legal/partner-resources/integration-partner-addendum/v1.mdx new file mode 100644 index 00000000000..0df69d5bcc4 --- /dev/null +++ b/apps/www/data/legal/partner-resources/integration-partner-addendum/v1.mdx @@ -0,0 +1,185 @@ +This Integration Partner Addendum (this "**Addendum**") contains terms and conditions that govern your participation in Supabase's Integration Partner Program (the "**Program**") and is a contract between Supabase and Partner. This Addendum is subject to Supabase's standard Master Partner Program Agreement, currently available on Supabase's website at [https://supabase.com/legal/partner-resources/master-partner-program-agreement](https://supabase.com/legal/partner-resources/master-partner-program-agreement) unless otherwise agreed by the Parties in writing (“**MPPA**”). Capitalized terms not otherwise defined in this Addendum will have the respective meanings assigned to them in the MPPA. + +This Addendum becomes binding and effective on Partner upon signature of a Program Authorization granting Partner the right to participate in the Program. + +## 1\. Background. + +Supabase provides access to the Services to existing and prospective End-Customers who may benefit from the availability of integrations of Partner's software, mobile applications or other technology-based resources (the “**Partner's Platform**”) with the Services (such integrations to be referred to herein as the “**Technology Integration(s)**”). Partner desires to create Technology Integration(s) and to offer such Technology Integration(s) to the existing and prospective End-Customers of Supabase, including via the marketplace of integrations that Supabase makes available to End-Customers within the Services and on its website(s) (“**Supabase Marketplace**”). Partner shall provide no other services relevant to the Services to End-Customers, other than as expressly authorized by the Agreement, and solely in accordance with the terms of the Agreement, unless otherwise agreed in writing by the Parties. + +## 2\. Publication of Technology Integration(s). + +Partner may only publish, release, or otherwise share or make available Technology Integration(s) with End-Customers, including via the Supabase Marketplace, that have received final approval in writing from Supabase (“**Publication**”). Publication shall be at Supabase’s sole discretion, not to be unreasonably withheld, and Supabase shall determine the qualification of a Technology Integration for Publication pursuant to the terms of this Addendum and Partner’s compliance with the Agreement. The scope of the Technology Integration(s) including applicable integration type, attribution mechanism, and placement formats, while provided for in the applicable Program Authorization, to the extent applicable, remain subject to Supabase's sole discretion regarding design and user interface changes, with reasonable notice provided to Partner for material changes. Additionally, Supabase may adjust Partner’s Supabase Marketplace placement, visibility, or participation in the Program based on performance metrics including reliability, security, support responsiveness, and customer adoption. Upon approval of Publication of a Technology Integration, Partner grants to Supabase a non-exclusive, revocable (solely as set forth in this Addendum), worldwide, non-transferable (except in compliance with Section 20 of the MPPA), non-sublicensable, fully paid-up, royalty-free license solely to (a) host, link to, reproduce, publicly perform, publicly display, test, distribute, make available, and use the Technology Integration(s), in each case for the purposes of making the Technology Integration(s) available through the Supabase Marketplace to End-Customers pursuant to this Addendum; and (b) reproduce, perform, display, use and access the Technology Integration(s) for administration and demonstration purposes in connection with the operation and marketing of the Supabase Marketplace. + +## 3\. Development of Technology Integrations. + +The Parties may work collaboratively to determine the exact features and functionalities of the Technology Integration(s). Throughout the development of the Technology Integration(s), Partner shall consult with Supabase and act on Supabase's advice, both in Partner's use of the Services and otherwise. Accordingly, each Party shall: + +### 3.1 Supabase Obligations. + +### In the case of Supabase, (i) provide reasonable technical documentation and support, to assist Partner in the successful completion and implementation of the Technology Integration(s); and (ii) monitor the availability of the Services and work with the Partner to resolve technical issues and errors relevant to the Services that may arise from time to time. + +### 3.2 Partner Obligations. + +In the case of Partner, ensure that the Technology Integration(s) comply with the standards and requirements described in the User Guide, including the Supabase Shared Responsibility Model available at [https://supabase.com/docs/guides/deployment/shared-responsibility-model](https://supabase.com/docs/guides/deployment/shared-responsibility-model), and any other technical documentation that Supabase may reasonably provide Partner. Without limiting the foregoing, a Technology Integration shall not, at any time, have fewer features, less functionality, or poorer performance, availability, or support than the same tier of such same or substantially similar product, software, or application offered by Partner to End Customers via any other online distribution service or channel, including any website or distribution method operated by Partner, unless (i) Partner makes such features, functionality, performance, availability, or support available to the same tier of Technology Integration(s) published in the Supabase Marketplace within thirty (30) days of such features, functionality, performance, availability, or support first being offered elsewhere, or (ii) the Parties otherwise agree in writing. In addition, Partner shall grant to each End Customer a limited, revocable, non-exclusive, non-sublicensable (except as needed for operation of the Technology Integration(s)), non-transferable worldwide right or license to perform, display, and use the Technology Integration(s)and any content contained in, accessed by or transmitted through the Technology Integration(s) in connection with the Supabase Marketplace, under the separate end user license agreement in its Technology Integration(s) that will govern the End Customer’s rights to the Technology Integration(s) (the “**EULA**”). Partner must include: (i) the EULA and (ii) a separate privacy policy in its Technology Integration(s) that accurately discloses all of Partner’s collection, use and disclosure of personal information and data and complies with Applicable Law. Partner acknowledges and agrees that the applicable EULA for each Technology Integration is solely between Partner and the End Customer. Supabase shall neither be party to, nor have any liability whatsoever, under any EULA or privacy policy between Partner and any End Customer. Notwithstanding the foregoing, End Customers’ access and use of Supabase Marketplace and the rights and obligations of Supabase to End Customers and vice versa shall be subject to the Service Terms. + +## 4\. Maintenance of Technology Integration(s). + +### 4.1 Marketing and Promotion. + +Partner shall collaborate with Supabase to assist Supabase in the incorporation of references to the Technology Integration(s) in its marketing materials as may be described in the Program Guide or as separately agreed to in a Program Authorization. Partner shall only publicize the Technology Integration(s)'s availability to its own websites and marketing efforts in accordance with Supabase's Branding Guidelines. + +### 4.2 Continuing Support. + +Partner shall: (i) update the Technology Integration(s) as necessary to accommodate for Supabase's updates and modifications to the Services; (ii) be fully responsible for the Technology Integration(s)’ upkeep and availability, including by ensuring the Technology Integration(s) remain active and functional in all respects throughout the period of its Publication; (iii) provide any and all required and requested support to End-Customers who are also customers of Partner and who utilize the Technology Integration(s); and (iv) provide a single point of contact to resolve technical issues that arise from the Technology Integration(s) in a timely manner. As a part of Partner’s compliance with 4.2(iii), Partner shall respond to Technology Integration(s) related issues within forty-eight (48) hours and use commercially reasonable efforts to resolve critical failures within seventy-two (72) hours. Persistent failure, defined as three or more unresolved critical failures within any ninety (90) day period, may result in removal of Supabase Marketplace placement at Supabase's reasonable discretion. + +## 5\. Revenue Share. + +This Section 5 applies only if Partner is designated an 'Integration Partner with Revenue Share Obligation' on a Program Authorization. Partner shall be considered so designated if such a title is listed to define Partner's Authorized Program(s) on a Program Authorization. If Partner is not so designated, this Section 5 does not apply. + +### 5.1 Key Terms Applicable to this Section 5\. + +(a) A "**Qualifying Customer**" is an End-Customer of Partner who first discovers or accesses Partner's product through the Supabase Marketplace, upon the earlier of: (i) the use of a Supabase-originated redirect in the Supabase Marketplace, such as a one-click authorization flow, or (ii) the actioning of a unique mechanism expressly agreed between Partner and Supabase in a Program Authorization. + +(b) “**Net Revenue**" means amounts actually collected by Partner from Qualifying Customers, excluding applicable taxes, refunds, credits, and chargebacks. + +(c) The applicable “**Revenue Share Rate**” is set forth in the applicable Program Authorization. + +(d) The “**Revenue Share Start Date**” is the date indicated in the Program Authorization on which Partner shall begin accruing obligations to pay Supabase the Revenue Share for any Qualifying Customers. + +### 5.2 Obligation. + +Partner shall pay Supabase a revenue share on revenue generated from Qualifying Customers calculated by applying the Revenue Share Rate to Net Revenue generated from Qualifying Customers during the applicable Revenue Share Period (“**Revenue Share**”). + +### 5.3 Revenue Share Period. + +The Revenue Share obligation applies to Net Revenue generated from each Qualifying Customer that so qualifies after the Revenue Share Start Date and for a period of two (2) years (“**Revenue Share Period**”). For the avoidance of doubt, the Revenue Share obligation is not extinguished or reset by reason of a Qualifying Customer's change of corporate name, acquisition, reorganization, or transfer to an affiliate of Partner, provided the underlying paid relationship is continuous. + +### 5.4 Partner Reporting. + +Partner is responsible for implementing and maintaining an attribution mechanism, as may be agreed to by the Parties in a Program Authorization. Partner shall provide Supabase with read-only access to Partner's attribution reporting dashboard (or a mutually agreed third-party attribution tool) within thirty (30) days of Publication and shall maintain such access throughout the Term. Supabase shall have the right to implement its own independent first-party tracking pixels, parameters, or referral identifiers within Supabase-controlled surfaces for validation purposes. In addition, Partner shall deliver a written Revenue Share report to Supabase within seven (7) days following the end of each calendar month following Publication (“**Revenue Share Report**”). Each Revenue Share Report shall include: (i) the number of Qualifying Customers active during the reporting period; (ii) Net Revenue generated from Qualifying Customers; (iii) the calculated Revenue Share amount owed to Supabase; (iv) a customer-level summary (which may use anonymized or pseudonymous identifiers) showing, for each Qualifying Customer: the date of first attribution, cumulative Net Revenue to date, and Revenue Share paid to date; and (v) any other metrics agreed in a Program Authorization. + +### 5.5 Audit Rights. + +Supabase may, upon fifteen (15) days' prior written notice, audit Partner's records related to Revenue Share calculations and the Revenue Share Report no more than twice per calendar year, provided that Supabase may audit more frequently upon reasonable suspicion. Partner shall maintain records for at least two (2) years following each Revenue Share Period. If any audit reveals an underpayment of five percent (5%) or more of the Revenue Share owed in the audited period, Partner shall bear all reasonable costs of the audit and shall remit the underpaid amount plus interest per Section 5.6 within fifteen (15) days of the audit finding. + +### 5.6 Payment Terms. + +Revenue Share payments shall be settled monthly. Supabase shall issue Partner an invoice for Revenue Share amounts owed for the applicable reporting period, promptly following Supabase’s receipt of each Revenue Share Report. Revenue Share payments shall be made by Partner to Supabase within fifteen (15) days following the receipt of invoice from Supabase, in United States Dollars (USD), via wire transfer or another mutually agreed method. Overdue amounts accrue interest at the lesser of 1.5% per month or the maximum rate permitted by Applicable Law, from the due date until actual payment. In addition, if any Revenue Share payment remains outstanding for more than thirty (30) days past its due date, Supabase may, at its sole discretion and without further notice, suspend or reduce Partner's Supabase Marketplace placement until all overdue amounts (including accrued interest) are paid in full. Such suspension shall not constitute a breach of this Agreement by Supabase and shall not relieve Partner of any accrued payment obligations. Supabase must notify Partner of any alleged calculation error within forty-five (45) days of receiving the applicable Revenue Share Report. Reports not disputed within this period are deemed accepted. The Parties shall resolve any timely dispute in good faith. + +### 5.7 Tax. + +All Revenue Share amounts payable to Supabase under this Agreement are exclusive of all sales, use, gross receipts, value-added (VAT), goods and services (GST), and other taxes, levies, imposts, duties, or governmental charges of any nature (collectively, “**Taxes**”). Except for Taxes based on Supabase’s net income, personnel, or assets, Partner shall be solely responsible for all Taxes chargeable on or in respect of the Revenue Share, payable in addition to, and without reduction of, the Revenue Share. All Revenue Share amounts shall be paid free and clear of, and without any deduction or withholding for or on account of, any Taxes; if Partner is required by Applicable Law to deduct or withhold any Taxes, Partner shall remit them in a timely manner in accordance with Applicable Law and shall not offset or reduce any Revenue Share payable to Supabase on account of such remittance. If a government authority determines that any amounts paid by Partner to Supabase are subject to any Taxes, or if Supabase is otherwise required by Applicable Law to charge, collect, account for, or remit any Taxes in respect of receipts received from Partner, Partner shall pay or reimburse Supabase the full amount thereof, together with any interest or penalties, in addition to and without reduction of the Revenue Share and any other amounts owed to Supabase; provided that this sentence does not apply to Taxes based on Supabase’s net income, personnel, or assets. The Parties’ obligations under this Section 5.7 survive any expiration or termination of this Agreement. + +## 6\. Access and Use of the Services. + +Subject to the Service Terms and except as otherwise expressly provided in the Agreement, Supabase grants Partner the right to access and use the Services solely to assist in Partner's development and maintenance of the Technology Integration(s). This right terminates upon termination of this Addendum, and Partner's rights and remedies with respect to its use of the Services shall at all times be governed by the Service Terms. Partner is not itself granted a subscription or license to the Services for its own internal use, nor is it granted any right to resell or grant third parties the right to use the Services under this Addendum; any such rights would be subject to a separate agreement between the Parties. + +## 7\. Partner Responsibilities and Restrictions; Suspension. + +### 7.1 Partner Responsibilities. + +#### (a) Direct. + +As between the Parties, Partner shall be solely responsible for: (i) obtaining authorizations from joint customers of Supabase and Partner as may be necessary to push and/or pull data of such joint customers through the Technology Integration(s); (ii) using commercially reasonable efforts to prevent the introduction of Harmful Code to: (a) any joint customers' systems, platforms, services, software, devices, sites and/or networks; or (b) the Services; (iii) compliance with Applicable Law, including Applicable Data Protection Law in the development, and maintenance, and use of the Technology Integration(s); (iv) implementing and maintaining appropriate technical and organizational security measures consistent with industry standards as applicable to the development and maintenance of the Technology Integration(s); (v) notifying Supabase in writing within seventy-two (72) hours of any breach of security leading to the unauthorized access to or use of data flowing through the Technology Integration(s); (vi) completing Supabase’s integration security review prior to public production launch; and (vii) the security, integrity, and legality of Partner’s Platform. Partner shall make no representations or warranties with respect to the Services or Supabase's associated support offerings to its customers or prospects and shall maintain adequate insurance coverage and minimum coverage limits for its business as required by any Applicable Law. Partner's lack of or insufficiency of insurance coverage shall not limit any liability Partner may have under this Addendum. For purposes of this clause, “Harmful Code” means code, files, scripts, agents or programs intended to do harm, including any code containing viruses, Trojan horses, worms or like destructive code, code that self-replicates or code that contains a "timeout" feature to prevent access and use at some future date. + +#### (b) Customer User Monitoring Obligation. + +To the extent relevant to the specific Technology Integration(s), Partner shall promptly (and in no event later than twenty-four (24) hours) terminate, disable, or otherwise deactivate any Customer User account or other Technology Integration(s) use by a Customer User that Partner suspends, blocks, terminates, or otherwise restricts due to suspected or actual abuse, fraud, violation of applicable law, or breach of Partner’s terms of service. To the extent Partner is technically unable to directly terminate or deactivate such Customer User, Partner shall notify Supabase within twenty-four (24) hours and provide sufficient identifiers (including project IDs or other mutually agreed identifiers) to enable Supabase to take action. Partner shall implement and maintain an automated mechanism (including API-based signaling or other technical integrations specified by Supabase) to (i) effectuate such deactivation and (ii) where applicable, transmit notices to Supabase in real time or near real time. Supabase reserves the right, but not the obligation, to independently suspend, throttle, restrict, or permanently disable any such Customer User, or associated resources at any time to mitigate security, operational, or financial risk. “**Customer User**” means an individual employee, agent or contractor of an End-Customer for whom access to the Services have been granted by Supabase pursuant to a contract signed by Supabase and the End-Customer. + +### 7.2 Partner Restrictions. + +Partner shall not, shall not attempt, or assist or permit any third party to: (i) access any endpoints of the Services other than those endpoints that Supabase has agreed that Partner may access in writing, even if the Partner has technical access to additional endpoints; (ii) use or access the Services in a manner that exceeds any express request volume provided by Supabase (or otherwise, a reasonable request volume), and as may be adjusted from time to time; (iii) intentionally submit queries to the Services (whether demo or demo environment) which fail to contain all required parameters; (iv) use or access the Services beyond the minimum extent reasonably necessary to develop and manage the Technology Integration(s); (v) push or pull any data which it does not own into or from the Services that it has not been explicitly authorized by the data owner to share with Supabase; (vi) bypass the security or authentication protocols of the Services; (vii) intentionally interfere with or disrupt: (a) any features or functionalities that are embedded in or included with the Services, (b) Supabase's monitoring of the Services, or (c) the servers or networks providing or hosting the Services; (viii) use the Services, any data obtained through the Services, or any Technology Integration(s): (a) in any manner or for any purpose that violates any Applicable Law or any right of any person or entity, including but not limited to Intellectual Property Rights, rights of privacy, and rights of personality, (b) in a false or misleading manner, or in any manner inconsistent with this Addendum or the Service Terms, or (c) in a way that may be offensive, profane, obscene, libelous to Supabase, Supabase's End-Customers or prospects. + +### 7.3 Data Processing. + +#### (a) Artificial Intelligence. + +### If any Technology Integration(s) uses or incorporates any AI, such use must be fully disclosed to End Customers in advance, including in Partner’s EULA and, as legally required, in the Privacy Policy, and Partner’s development and use of AI must comply with all relevant Applicable Laws. Any use or incorporation of AI without such disclosure, or otherwise in violation of this Section, shall be considered a material breach of this Addendum. Partner shall (i) reasonably test the use or incorporation of AI with various inputs to ensure that outputs do not violate this Agreement; (ii) have a mechanism for End Customers to report feedback to Partner related to errors, bugs, improper, or undesired outputs; (iii) inform End Customers of the appropriate use cases, best practices, and limitations of the AI used or incorporated in a Technology Integration(s); and (iv) not use Supabase’s End Customer’s data or source code to train or fine tune Partner’s or any third party’s AI models. “AI” means generative artificial intelligence that is designed to take input and generate output of any kind, including but not limited to images, video, music, speech, text, software code, and product designs. + +#### (b) Personal Data Protection. + +Any Personal Data processed in connection with this Addendum shall be handled as follows: + +(i) _Roles_. Except where the Parties expressly agree otherwise in a Program Authorization, each Party acts as an independent controller (or equivalent role under Applicable Data Protection Law) with respect to Personal Data it collects, receives, or determines the purposes and means of processing for in connection with the Technology Integration(s); neither Party processes Personal Data on behalf of the other except as expressly designated in writing. + +(ii) _Compliance_. Each Party shall comply with all Applicable Data Protection Laws in its processing of Personal Data, including obtaining and maintaining all notices, consents, and lawful bases required for the disclosures and processing contemplated by the Technology Integration(s). + +(iii) _Security_. Partner shall implement and maintain appropriate technical and organizational measures designed to protect Personal Data against unauthorized or unlawful processing and against accidental loss, destruction, damage, alteration, or disclosure, consistent with the standard set forth in Section 7.1(a)(iv). + +(iv) _International Transfers_. To the extent the Technology Integration(s) involve a transfer of Personal Data across jurisdictions, the transferring Party shall ensure a valid transfer mechanism is in place (such as the EU Standard Contractual Clauses, the UK International Data Transfer Addendum, or another lawful mechanism), and the Parties shall reasonably cooperate to execute any additional documentation required under Applicable Data Protection Law. + +(v) _Incidents_. Partner shall notify Supabase of any Personal Data Breach in accordance with Section 6.1(a)(v) and shall reasonably cooperate with Supabase in connection with the investigation, remediation, and notification of any such incident. + +(vi) _Data Subject Rights and Regulator Inquiries_. Each Party shall, at its own cost, reasonably cooperate with the other in responding to any verified data subject request or competent supervisory authority inquiry to the extent such request or inquiry relates to Personal Data processed in connection with the Technology Integration(s). + +(vii) _Sub-processors_. To the extent Partner engages any third party to process Personal Data received from or through the Services in connection with the Technology Integration(s), Partner shall impose on such third party data protection obligations no less protective than those set forth in this Section 7.3(b) and shall remain liable for the acts and omissions of such third parties. + +(viii) _Return or Deletion_. Upon expiration or termination of this Addendum, or upon Supabase's written request, Partner shall, at Supabase's option, return or securely delete Personal Data received from or through the Services, except to the extent retention is required by Applicable Law or for the establishment, exercise, or defense of legal claims. The Parties agree that this Section 7.3(b) constitutes the data protection terms governing Personal Data processed under this Addendum, and no separate data processing agreement shall be required unless and until the Parties' processing activities materially change such that one is required by Applicable Data Protection Law. + +### 7.4 Developer Credentials. + +Solely to the extent Supabase issues Partner any developer credentials, (such as tokens or electronic keys) with respect to the Services (“**Developer Credentials**”), Partner shall: (i) use the Developer Credentials to access the Services; (ii) not misrepresent or mask its identity when utilizing the Services; and (iii) hold such Developer Credentials in confidence and not share with, or transfer the Developer Credentials to, any third party without Supabase's prior written consent (which can be revoked at any time). Supabase hereby reserves the right to update Partner's Developer Credentials from time to time and Partner shall be obligated to use the new Developer Credentials and shall no longer access the Services using any deprecated Developer Credentials. + +### 7.5 Suspension and Revocation. + +Supabase reserves the right to suspend or discontinue the Partner's access to all or any portion of the Services, revoke the rights granted in Section 6, and/or remove Partner’s Technology Integration(s) from the Services at any time, at Supabase's sole discretion, provided that Supabase shall use reasonable efforts to provide the Partner with at least thirty (30) days' notice prior to taking any such action. Notwithstanding the foregoing, in the event that Supabase reasonably determines that Partner's access to the Services, or its Technology Integration(s), poses a security or privacy risk to Supabase or any other party and that risk cannot be cured by Partner in a reasonable amount of time, then Supabase may, at its sole discretion, immediately (a) suspend or discontinue the Partner's access to all or any portion of the Services or remove the Technology Integration(s) from the Services, or (b) revoke the rights granted in Section 6, with or without prior notice to the Partner. Any exercise of this right by Supabase shall result in no liability or remedy owed to Partner unless otherwise separately agreed by the Parties in writing. + +## 8\. Intellectual Property. + +### 8.1 Supabase IP Rights. + +Partner acknowledges and agrees that as between Supabase and Partner, Supabase shall own all rights, titles and interests in and to the Intellectual Property Rights related to or arising out of the Services, including, without limitation general knowledge and techniques developed or used by the Services. Nothing in this Addendum shall be construed to grant the Partner any ownership right in the Services, any derivative works of the Services, or the related Intellectual Property Rights. Additionally, while Partner is under no obligation to provide feedback, capability or feature suggestions, or bug reporting regarding the Services (“**Feedback**”), to the extent Partner does provide such Feedback, the Partner grants to Supabase a worldwide, perpetual, irrevocable, royalty-free license to exercise all rights in the Feedback. + +### 8.2 Partner IP Rights. + +Supabase acknowledges and agrees that as between Supabase and Partner, the Partner owns all right, title and interest in and to the Intellectual Property Rights in and to the Partner's Platform and, except as expressly stated otherwise in this Addendum, the Technology Integration(s), and any associated services, documentation, prototypes, models, computer source code, source files, and any other computer files and materials (regardless of form or format) which the Partner creates in connection with the Technology Integration(s). For clarity, nothing in this Addendum, or the Agreement shall be construed to grant Supabase any ownership right in the Partner’s Platform or its related Intellectual Property Rights. Notwithstanding the foregoing, upon final approval of the Technology Integration(s) by Supabase, Partner hereby authorizes Supabase to market, promote, and subject to Publication, the Technology Integration(s) as Supabase deems appropriate. + +### 8.3 No Jointly Developed or Held Intellectual Property; No Implied Rights. + +The Parties understand that they do not anticipate to jointly develop any intellectual property under this Addendum, and to the extent they do, the Parties will handle ownership and licensing of such intellectual property in good faith and as mutually agreed upon in a separate written agreement. Additionally, as of the Effective Date of the Agreement, no intellectual property is held between the Parties. Subject to the limited licenses expressly provided in this Agreement, nothing in this Agreement (including this Addendum) transfers or assigns to a Party any of the other Party’s Intellectual Property Rights in its Marks, technology, or otherwise, and no rights are implied. + +## 9\. Representations and Warranties. + +In addition to the representations and warranties provided by the Parties in the MPPA, Partner further represents and warrants that: (a) Partner’s Technology Integration(s) comply with all Applicable Data Protection Laws and Applicable Law relevant to consumer protection; (b) Partner has obtained all End-Customer and Customer User consents required for the Processing of data as relevant to its Technology Integration(s); and (c) Partner will not use the Technology Integration(s) for any unlawful purpose. + +## 10\. Applicability of MPPA. + +This Addendum is subject to the terms and conditions of the MPPA. Without limiting the foregoing, and for clarity of the Parties: (i) Partner's obligations under the MPPA with respect to its conduct and its compliance with Applicable Laws, including those relating to Personal Data, anti-bribery and anti-corruption, and export controls and trade sanctions, extend to this Addendum; (ii) except as otherwise expressly provided in this Addendum, Partner's remedies with respect to its participation in the Program, and use of the Services, shall be solely as provided in the MPPA and this Addendum; and (iii) Sections 6, 7, 11, 12, and 19 through 24 of the MPPA shall, in addition to the remainder of the MPPA, apply to this Addendum. For clarity, no End-Customer or Customer User shall be deemed a third-party beneficiary of this Addendum, or the Agreement. + +## 11\. Term and Termination. + +### 11.1 Term. + +Notwithstanding any contrary provision in the MPPA, the term of this Addendum will continue through the expiration or earlier termination of the MPPA, or the end of the Publication of the Technology Integration(s), whichever is earlier. + +### 11.2 Termination Rights. + +In addition to the termination rights of the Parties expressly provided in the MPPA, either Party may terminate this Addendum and the availability of any Technology Integration(s), effective on written notice to the other Party, if the other Party materially breaches this Addendum, and such breach (if capable of cure) remains uncured 30 days after the non-breaching Party provides the breaching Party with written notice of such breach. Additionally, Supabase may terminate this Addendum and the Publication of any Technology Integration(s) for convenience upon ninety (90) days prior written notice to the other Party. + +### 11.3 Effects of Termination. + +Upon expiration or earlier termination of this Addendum: (a) all rights granted to Partner with respect to the Services will terminate effective as of the effective date of termination; (b) any accrued Revenue Share obligations survive; and (c) in the event of Supabase's termination pursuant to the last sentence of Section 11.2 of this Addendum, Partner shall continue to comply with Section 4 of this Addendum through the term of this Addendum. + +### 11.4 Survival. + +In addition to Section 11.3, the following provisions of this Addendum shall survive any expiration or termination of this Addendum: Section 1 (solely with respect to defined terms), Section 5 (Revenue Share), Section 7.2 (Partner Restrictions, to the extent of Partner's continuing use, if any, of data or materials obtained under this Addendum), Section 8 (Intellectual Property), Section 10 (Applicability of MPPA), Section 11.3 (Effects of Termination), this Section 11.4 (Survival), Section 12 (Indemnification), Section 13 (Limitations of Liability), and Section 14 (Miscellaneous). In addition, any right or obligation of the Parties under this Addendum that, by its nature, is intended to survive termination or expiration (including any accrued payment obligations and any claims arising from acts or omissions occurring prior **to termination or expiration) shall so survive.** + +## 12\. Indemnification. + +In addition to the obligations of the Parties in the MPPA, and subject to the indemnification procedures described in the MPPA: + +### 12.1 Supabase Indemnification. + +Subject to the remainder of this Section 12.1, Supabase agrees to defend, indemnify and hold harmless Partner and Partner Indemnitees, from and against any and all Losses arising out of or related to any Third-Party Claim alleging that the Services or Partner's use thereof infringes or violates such third party's Intellectual Property Rights (each, a "**Partner Infringement Claim**"). Supabase will pay all Losses incurred by and damages against the Partner Indemnitees but will not be responsible for any compromise or settlement made without its express prior written consent. If the Services become, or in Supabase's opinion are likely to become, the subject of a Partner Infringement Claim, Supabase may, but is not obligated to, (i) modify or replace the Services to make them non-infringing; (ii) procure any rights from a third party necessary to provide the Services; or (iii) replace the Services with work product that is materially equal in capabilities, capacity, performance, and ease of use but is non-infringing. If none of the foregoing remedies is available to Supabase on commercially reasonable terms, Supabase may terminate the Agreement. Supabase will have no obligation to indemnify Partner for a Partner Infringement Claim to the extent it arises from any of the following: (a) unauthorized alteration of the Services; (b) use of the Services in combination with apparatus, hardware, software, or services not provided or authorized by Supabase; (c) any use of the Services by Partner that violates any Applicable Law; (d) use of the Services in a manner that violates any Applicable Law or breaches the Agreement, including this Addendum; (e) Partner's Platform; or (f) the Technology Integration(s) (including activities conducted with Partner's access credentials to the Services), subject to Supabase's security and processing obligations under the Agreement. THIS SECTION 12.1 OF THIS ADDENDUM STATES SUPABASE'S ENTIRE LIABILITY AND PARTNER'S EXCLUSIVE REMEDIES FOR ANY CLAIM OF INTELLECTUAL PROPERTY RIGHTS INFRINGEMENT OR MISAPPROPRIATION BY A THIRD PARTY RELEVANT TO THE SERVICES. TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, PARTNER (ON ITS OWN BEHALF AND ON BEHALF OF ANY PERSON OR ENTITY AUTHORIZED TO USE THE SERVICES BY PARTNER) COVENANTS NOT TO SUE OR MAKE OR ASSERT AGAINST SUPABASE ANY CLAIM OF INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHT WITH RESPECT TO THE SERVICES PROVIDED TO PARTNER UNDER THE AGREEMENT. + +### 12.2 Partner Indemnification. + +Partner agrees to defend, indemnify and hold harmless Supabase and Supabase Indemnitees, from and against any and all Losses arising out of or related to any Third-Party Claim alleging: (i) Partner's violation of Section 7.2 of this Addendum; or (ii) Partner, Partner's Technology Integration(s), or Partner's Platform's infringement of such third party's Intellectual Property Rights. + +## 13\. Limitations of Liability. + +Solely with respect to the Parties' obligations under this Addendum, and to the fullest extent permitted by Applicable Law, except as otherwise expressly provided in this Section 13, in no event shall: (a) either Party, its Affiliates or their employees, agents, contractors, officers or directors be liable for any indirect, punitive, incidental, special, consequential or exemplary damages, including without limitation damages for business interruption, loss of profits, goodwill, use, data or other intangible losses arising out of or relating to this Addendum; or (b) either Party's cumulative and aggregate liability under this Addendum exceed the total Revenue Share amounts accrued under Section 5 in the twelve months prior to the event giving rise to the liability, provided that in no event shall such cap be less than fifty thousand United States Dollars (USD $50,000.00). The foregoing liability cap shall not apply to liabilities arising under this Agreement due to: (i) either Party's gross negligence, willful misconduct, or fraudulent misrepresentation or indemnification obligations, or (ii) Partner’s obligation to pay Revenue Share amounts accrued under Section 5\. Notwithstanding the foregoing, and solely to the extent permitted by Applicable Law, the aggregate liability of either Party for all claims arising under clause (i) above shall not exceed three hundred thousand United States Dollars (USD $300,000.00). + +## 14\. Miscellaneous. + +The MPPA and this Addendum is the complete and exclusive statement of the agreement between the Parties with respect to the Technology Integration(s) that Partner makes available on the Services. Any terms and conditions of any other instrument issued by Partner or any End-Customer in connection with the Technology Integration(s) which are in addition to, inconsistent with or different from the terms and conditions of the MPPA and this Addendum shall be of no force or effect. In the event any provision of this Addendum is deemed to conflict with a provision of the MPPA, the applicable provision of this Addendum shall control. Supabase may change this Addendum from time to time at its discretion. The date on which the Addendum was last modified will be updated at the top of this Addendum. Amendments to this Addendum will only take effect on Partner, on the renewal of this Addendum only when the Parties enter into a subsequent Program Authorization. diff --git a/apps/www/data/legal/partner-resources/mppa/v1.mdx b/apps/www/data/legal/partner-resources/mppa/v1.mdx new file mode 100644 index 00000000000..4f34fb83a5b --- /dev/null +++ b/apps/www/data/legal/partner-resources/mppa/v1.mdx @@ -0,0 +1,243 @@ +This Master Partner Program Agreement (this “**MPPA**”), and its applicable Program Addendums, and the Program Authorization which references this MPPA (together, the “**Agreement**”) is entered into between the Parties and contains the terms and conditions that govern your access to the Partner Portal and your participation in one or more Programs, and is a contract between Supabase Pte. Ltd. (Company Registration No.: 202005760H), a private limited company incorporated in the Republic of Singapore with its registered office at 65 Chulia Street \#38-02/03, OCBC Centre, Singapore 049513, a subsidiary of Supabase, Inc. (“**Supabase**”), and you or the entity or organization that you represent (“**Partner**”), (each of Supabase and Partner a “**Party**” and together the “**Parties**”) and, unless otherwise agreed by the Parties in writing, becomes binding and effective on Partner upon Partner and Supabase's signature on a Program Authorization (“**Effective Date**”). The Agreement replaces and supersedes all previous agreements and other communications (oral or written) between Partner and Supabase relating to the subject matter of the Agreement or the Programs. Capitalized terms not otherwise defined in this MPPA shall have the respective meanings assigned to them in Section 25\. + +## 1\. Program Authorization. + +Unless otherwise directed by Supabase in writing (email sufficient), including via a Program Authorization, Partner must apply to participate in a Program and receive approval from Supabase. Supabase will assess Partner's qualifications for the Program(s) based on the information provided and, depending on Program type, may request additional information. Supabase reserves the right to accept or reject any Partner application in its sole discretion. Partner's participation in any Program will be governed by the terms of this MPPA, and the applicable Program Addendum(s). If Supabase approves Partner to participate in a Program, the Parties will sign a Program Authorization. Such Program Authorization will designate the scope of authorization granted for Partner's participation in the indicated Programs and may designate a geographic restriction to Partner's authorized activities under the terms of the Agreement (“**Territory**”). + +## 2\. Program Tiers and Benefits. + +### 2.1 Tiers. + +Supabase may designate a “**Tier**” for Partner based on the level of Partner's participation in the Program(s) and other criteria, as set forth in the Agreement, Program Guide, the Partner Portal, or as otherwise indicated to Partner by Supabase from time to time, including in its initial Program Authorization. In such a case that Supabase does offer Partner a Tier, Supabase (i) reserves the right to review Partner's Tier periodically; (ii) may raise or lower Partner's Tier in its sole discretion; and (iii) will make commercially reasonable efforts to notify Partner of any such changes to Partner's Tier (including via email or through the Partner Portal). + +### 2.2 Benefits. + +Supabase may offer benefits to Partner based on its Tier. Supabase may, in its sole discretion, change the benefits available at, and the qualifying criteria for, each Tier from time to time and may modify or discontinue the Program(s), the Partner Portal, or Partner's participation in a Program(s) or access to the Partner Portal, at any time, upon reasonable notice. + +## 3\. Partner Obligations and Restrictions. + +### 3.1 Training and Certifications; Collaboration. + +Supabase may provide Partner with training focused on the marketing, use and promotion of the Services prior to its participation in any Program(s), and on an ongoing basis. Partner shall be required to participate in such training as instructed by Supabase from time to time, including to the extent Supabase offers certification programs. Additionally, upon Supabase's reasonable request, prior to its involvement in a Program and from time to time as reasonably requested by Supabase, Partner agrees to meet, either in person or via teleconference, to discuss the status of the relationship contemplated herein. + +### 3.2 Conduct. + +During the term of the Agreement, Partner shall conduct itself in a professional and competent manner, consistent with the Agreement. Unless separately authorized in writing by Supabase, including via an applicable Program Addendum, Partner shall: (i) not sell, resell, distribute, license, or sublicense the Services to any third party; (ii) not directly or indirectly engage in any unfair, unethical, misleading, disparaging, or deceptive acts or practices that are or might be detrimental to the public or the goodwill or reputation of Supabase or its products or the Services, including making any statements, representations or depictions concerning Supabase or the Services, or the services that Partner provides to its own customers, that are false, misleading, deceptive, or inconsistent with the Program Content or User Guide or other materials (including price lists) published or otherwise supplied by Supabase from time to time; (iii) not make any commitments, warranties, guarantees, or misleading statements to any third parties with respect to the features or functionalities of the Services (including any technical specifications), the expected benefits of use of the Services, the pricing thereof, the origin thereof, Partner's relationship with Supabase, or Partner's duties under the Agreement; (iv) not do anything or act in any way that may diminish the brand or reputation of Supabase; (v) not bid on Supabase's branded keywords in paid advertising; or (vi) not distribute any unsolicited bulk emails (spam) mentioning or referencing Supabase or the Services. Except as may be expressly provided in an applicable Program Addendum(s), Partner has no authority to (a) negotiate any contract for or on behalf of Supabase; (b) represent itself as an agent of Supabase, or (c) bind Supabase to any contract, representation, or understanding, including those concerning Supabase or the Services, or any other products or services offered by Supabase. + +## 4\. Partner Portal. + +### 4.1 Use. + +Any use of any Partner Portal that Supabase may make available from time to time is subject to this MPPA and the Site Policies. Partner may only access and use any such Partner Portal, or other materials as may be provided to Partner by Supabase including via the Partner Portal, in accordance with the Agreement and solely for the management of its relationship with Supabase. The Partner Portal may include links to third-party owned platforms and websites (“**Third-Party Sites**”). The Third-Party Sites are not under the control of Supabase and Supabase is not responsible for the content of any Third-Party Site and/or any links contained in the Third-Party Site(s). Partner understands that any access to and use of such Third-Party Sites shall be governed by the applicable terms and conditions, or licenses, referenced on such Third-Party Sites. Supabase is providing links to the Third-Party Site(s) to Partner only for Partner's convenience and Supabase is not responsible for any kind of loss or damage arising out of it, and the access to or any other act on such Third-Party Sites shall be entirely at Partner's risk. + +### 4.2 Profile. + +Partner may be invited to submit or publish information about itself via a Partner Portal if made available by Supabase (a “Profile”). Partner agrees that any information it provides in its Profile will be truthful and accurate, and that Supabase has the right to use, reproduce, display, and otherwise disclose the Profile to third parties solely for purposes relating to its business, and the Program(s). + +### 4.3 Responsibilities. + +Partner is responsible for all activities conducted with its Partner Portal login credentials and agrees to use reasonable efforts to prevent unauthorized access to or use of the Partner Portal. Partner shall contact Supabase promptly if any login credentials are lost, stolen or disclosed to an unauthorized person or if Partner reasonably believes the Partner Portal has been compromised. + +## 5\. Demo Account. + +Supabase may provide Partner with access to the Services in furtherance of Partner's participation in a Program (a “**Demo Account**”). Any Demo Account shall be restricted to Partner's internal use solely to allow Partner to understand and demonstrate the capability of the Services and shall otherwise be subject to the Service Terms. For clarity, Partner shall not submit Customer Data (as defined in the Service Terms) to the Demo Account. + +## 6\. Marks and Content. + +Each Party (“**Grantor**”) authorizes the other Party (“**Grantee**”) to use certain of Grantor's Marks and Content pursuant to this Section 6 during the Term. + +### 6.1 Marks. + +Grantee may use Grantor's Marks solely to promote Partner's Program participation and the Services. Partner's use of Supabase's Marks must comply with the Branding Guidelines and Partner shall include the Supabase Marks, as well as any required intellectual property notices, on all promotional materials related to the Services, including the Program Content. Any use by Grantee of Grantor's Marks must be consistent with the Agreement, and all goodwill associated with the use of the Grantor's Marks will inure solely to Grantor's benefit. Grantor has the right to control the nature and quality of Grantee's use of Grantor's Marks. Grantee shall not: (i) use Grantor's Marks in a manner that (a) misrepresents Grantee's relationship with Grantor or is otherwise misleading, or (b) that reflects negatively on Grantor, (ii) associate the Grantor's Marks with content that is unlawful in any manner, or which is otherwise harmful, threatening, defamatory, obscene, offensive, harassing, sexually explicit, violent, discriminatory, or otherwise objectionable in Grantor's sole discretion, or (iii) adopt, use, or attempt to register any trademarks, service marks, or trade names that are confusingly similar to the Grantor's Marks or in such a way as to create combination marks with the Grantor's Marks. If Grantor, in its sole discretion, determines any use by Grantee of Grantor's Mark is not in compliance with the Agreement, Grantee shall promptly modify or discontinue such use as directed by Grantor. + +### 6.2 Content. + +Grantee may reproduce and distribute Grantor's Content solely to promote Partner's Program participation and the Services. Without limiting the foregoing, Grantee acknowledges that except as expressly provided in this Section, and applicable Program Addendum(s), Grantee may not (i) use, reproduce, sell, sublicense, distribute or otherwise transfer any Content of Grantor to any third party or (ii) modify, alter or otherwise create derivative works of any Content of Grantor. + +### 6.3 Rights Granted. + +Grantor is responsible for ensuring it has all rights in and to Grantor's Marks and Content necessary to grant Grantee the rights under this Section 6\. Grantee acknowledges that all authorizations under this Section 6 with respect to Grantor's Marks and Content are limited, revocable, nonexclusive and, subject to Section 20, non-assignable and non-transferable. + +## 7\. Relationship. + +Supabase and Partner are independent contractors, and the Agreement does not create a joint venture, agency, fiduciary, employment relationship or partnership; use of the term "partner" refers only to Partner's participation in the applicable Program(s). Neither Party nor any of its respective Affiliates is an agent of the other for any purpose or has the authority to bind the other, and nothing in the Agreement or any Program creates any franchise relationship between the Parties. Partner's participation in any Program is on a nonexclusive basis, and Supabase is free to enter into the same or similar relationships on the same or different terms with other parties. Partner represents that its execution and performance of the Agreement does not conflict with or breach any contractual, fiduciary or other duty or obligation to which Partner is bound. + +## 8\. Compliance with Applicable Laws. + +Each Party agrees to comply with all Applicable Laws in the performance of its obligations and exercise of its rights under the Agreement. Without limiting the foregoing: + +### 8.1 Privacy Laws. + +Each Party shall comply with Applicable Data Protection Laws. Partner shall be solely responsible for providing any notices required by Applicable Law to, and receiving any consents and authorizations required by Applicable Law from, persons whose Personal Data it elects to share with Supabase. + +### 8.2 ABAC. + +Each Party shall comply with Applicable Laws concerning anti-bribery and anti-corruption, which may include the U.S. Foreign Corrupt Practices Act of 1977 and the UK Bribery Act 2010\. Each Party represents, warrants and covenants that in the performance of any activities under the Agreement that it has neither provided nor offered, nor will provide or offer, any illegal or improper bribe, kickback, payment, gift or thing of value to any Government Official or Close Family Member of any Government Official. Each Party agrees to promptly notify the other if it learns of any violation of the foregoing and Supabase may, at its sole option, immediately terminate the Agreement in the event of such notice, without liability. + +### 8.3 Export Laws. + +Each Party shall (a) comply with Applicable Laws administered by the applicable Government Entities imposing export controls and trade sanctions, which may include, but are not limited to the U.S. Commerce Bureau of Industry and Security, and the U.S. Treasury Office of Foreign Assets Control (“**Export Laws**”), including designating countries, entities and persons (“**Sanctions Targets**”) and (b) not directly or indirectly export, re-export or otherwise deliver any Content or Services to a Sanctions Target, or broker, finance or otherwise facilitate any transaction in violation of any Export Laws. Partner represents that it is not a Sanctions Target or prohibited from receiving any Program Content under Applicable Laws, including Export Laws. + +## 9\. Fees. + +Each Party shall, as applicable, pay any fees and costs solely as specified in this MPPA or the applicable Program Addendum(s). + +## 10\. Ownership. + +As between the Parties: (a) Partner owns all right, title and interest in and to Partner's Marks and Partner Content, including in each case all associated Intellectual Property Rights, and (b) Supabase owns all right, title and interest in and to Supabase's Marks, Program Content, Services, the User Guide and Feedback, including in each case all associated Intellectual Property Rights. Except for the rights expressly granted by one Party to the other in this MPPA or a Program Addendum, all rights are reserved by the granting Party. + +## 11\. Confidentiality. + +### 11.1 Confidential Information. + +As used in the Agreement, “**Confidential Information**” means any information disclosed by one Party, its Affiliates, business partners or their respective employees, agents or contractors (collectively, the “**Discloser**”) that is designated as confidential, either orally or in writing, or that, given the nature of the information or circumstances surrounding its disclosure, reasonably should be understood to be confidential. Confidential Information includes without limitation: (i) information relating to the Discloser's or its Affiliates' technology, customers, business plans, promotional and marketing activities, finances and other business affairs, including any such information made available by Supabase through the Partner Portal; (ii) third-party information that the Discloser is obligated to keep confidential; and (iii) the terms of the Agreement. However, Confidential Information does not include any information that: (a) was known to the Party that receives any Confidential Information (the “**Recipient**”) prior to receiving the same from the Discloser in connection with the Agreement; (b) is independently developed by the Recipient without reference to or use of the Discloser's Confidential Information; (c) is acquired by the Recipient from another source without restriction as to use or disclosure; or (d) is or becomes publicly available through no fault or action of the Recipient. + +### 11.2 Use. + +The Recipient shall not (i) use the Discloser's Confidential Information for any purpose outside the scope of the Agreement without the Discloser's prior written consent or (ii) disclose the Discloser's Confidential Information to any person or entity, except to the Recipient's employees, agents, contractors and service providers who (a) are bound by non-use and non-disclosure obligations at least as protective as those contained in the Agreement and (b) have a need to know the Confidential Information for the Recipient to exercise its rights or perform its obligations under the Agreement. Notwithstanding the foregoing, the Recipient may disclose the Discloser's Confidential Information to the limited extent any use or disclosure is required by Applicable Law or a valid and binding order of a governmental body (such as a subpoena or court order), provided that, to the extent permitted under Applicable Law, the Recipient uses reasonable efforts to give the Discloser reasonable advance notice thereof to afford the Discloser an opportunity to intervene and seek an order or other appropriate relief for the protection of its Confidential Information. In the event of any breach or threatened breach by the Recipient of its obligations under this Section, the Discloser will be entitled to seek injunctive and other equitable relief to enforce such obligations. + +### 11.3 Deletion. + +Promptly following the request of Discloser, Recipient will return to Discloser, or destroy, all Confidential Information of Discloser that are in written, electronic, or other tangible form, including, without limitation, all copies, extracts, and derivatives of such Confidential Information. On request of Discloser, Recipient will confirm to Discloser in writing Recipient's compliance with this Section 11.3. Notwithstanding the foregoing, Recipient may retain Confidential Information (i) contained in electronic archives and backups made in the ordinary course of business, (ii) that such party is required by law to maintain; or (iii) that such party reasonably determines necessary to demonstrate to the other party or any regulatory authority Recipient's compliance with the Agreement or any Applicable Law or regulation; provided that all such Confidential Information retained will remain subject to the protections set forth herein for so long as it remains in Recipient's possession or control. + +## 12\. Prospect Information. + +During the Term, each Party may provide the other Party identifying or other business and Service use information relating to prospective or actual End-Customers of the Services (“**Prospect Information**”), including via the Partner Portal. Without limiting clauses (a) and (b) of Section 11.1, each Party will treat Prospect Information, and any Personal Data therein, as Confidential Information. Each Party will only Process Prospect Information in accordance with the Agreement and Applicable Laws, including Applicable Data Protection Laws, and expressly understands that (i) it is prohibited from selling and otherwise sharing the Prospect Information with third parties and (ii) it shall only use the Prospect Information for the purpose of providing the services contemplated by the Agreement, and insights, service and feature announcements and other reporting to End-Customers. Unless expressly authorized by Supabase in writing, Partner may not use any Prospect Information provided by Supabase to market Partner's products or services. Each Party will be solely responsible for any Prospect Information it elects to provide to the other Party, including providing any required notices to, and receiving any required consents and authorizations from, the prospects, customers and individuals that are the subjects of such Prospect Information. + +## 13\. Publicity. + +Except as expressly provided in the Agreement, including any Program Addenda or Program Authorization, neither Party shall issue or release any announcement, statement, press release or other publicity or marketing materials relating to the Agreement, or otherwise use the other Party's Marks, without the prior written consent of the other Party. Notwithstanding the foregoing, Supabase may publicly identify Partner as a partner of Supabase in its promotional materials, interviews, partner lists, and other promotional activities. + +## 14\. Representations and Warranties. + +Partner represents and warrants that it (i) has obtained and will obtain and maintain any and all permits, licenses, authorizations, permissions, and/or certificates that may be required in any jurisdiction, by any regulatory or administrative agency or otherwise, in connection with the marketing of the Services, performance of its obligations, and its compliance with, the Agreement and (ii) will comply with all Applicable Laws. Each Party represents, warrants, and covenants that it possesses the right and authority to enter into the Agreement and to exercise its rights and perform its obligations hereunder. + +## 15\. Disclaimers. + +EXCEPT AS EXPRESSLY PROVIDED IN THE AGREEMENT: (a) THE PROGRAM CONTENT, SERVICES, USER GUIDE, AND ANY BENEFITS OR OTHER MATERIAL THAT SUPABASE MAY MAKE AVAILABLE IN CONNECTION WITH THE AGREEMENT OR ANY PROGRAM, ARE PROVIDED BY SUPABASE ON AN "AS IS" AND "AS AVAILABLE" BASIS AND (b) NEITHER PARTY MAKES ANY WARRANTY OR GUARANTEE OF ANY KIND, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, AND EACH PARTY SPECIFICALLY DISCLAIMS ALL WARRANTIES, WHETHER IMPLIED, EXPRESS, OR STATUTORY, INCLUDING ANY IMPLIED WARRANTY OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, AND ALL WARRANTIES ARISING FROM COURSE OF DEALING, USAGE OR TRADE PRACTICE, TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW. + +## 16\. Term and Termination. + +### 16.1 Term. + +This MPPA, including any applicable Program Addendum(s) will remain in effect until terminated as set forth herein or in a Program Authorization, except that this MPPA will automatically terminate upon termination of Partner's participation in all Programs (the “**Term**”). + +### 16.2 Termination. + +Except as otherwise provided in a Program Addendum, either Party may terminate this MPPA, or any Program Addendum (and its participation in the applicable Program), for any or no reason by giving at least 30 days' prior written notice. Additionally, either Party may terminate this MPPA, or any Program Addendum (and its participation in the applicable Program) effective on written notice to the other Party, if the other Party materially breaches this MPPA, or the applicable Program Addendum, and such breach (if capable of cure) remains uncured 30 days after the non-breaching Party provides the breaching Party with written notice of such breach. + +### 16.3 Effect of Termination. + +If this MPPA is terminated for any reason, except as otherwise expressly set forth in in a Program Addendum: (i) all rights and licenses granted by Partner or Supabase under the Agreement to the other will terminate; (ii) each Party shall cease to identify itself or the other as, and will not otherwise hold itself or the other out as, a Program partner or participant; (iii) each Party shall immediately discontinue all use of the other's Marks, Program Content and Demo Accounts, as applicable; and (iv) upon either Party's written request, the other Party will immediately return or destroy all Confidential Information of the requesting Party. + +### 16.4 Survival. + +The provisions set forth in Sections 6 through 24, and any other right or obligation of the Parties in the Agreement that, by its nature, should survive termination or expiration of the Agreement, will survive any expiration or termination of the Agreement. + +## 17\. Indemnification. + +### 17.1 Supabase Indemnification. + +#### (a) Supabase will defend, indemnify, and hold harmless Partner and its respective directors, officers, employees, representatives, and agents (collectively, the "Partner Indemnitees") from and against any and all claims, losses, damages, suits, fees, judgments, compromises, or settlements, costs, and expenses (“Losses”) to the extent based upon or arising from a third-party claim (collectively, “Third-Party Claims”) alleging that the Program(s), or the Supabase Marks (collectively, the “Covered Materials”) infringe or violate any third party Intellectual Property Rights. Supabase will pay all Losses incurred by and damages against the Partner Indemnified Parties but will not be responsible for any compromise or settlement made without its express prior written consent. + +#### (b) Such indemnity pursuant to 17.1(a) is specifically exclusive of any such claims to the extent they arise or result, directly or indirectly, from Partner's: (i) unauthorized alteration of the Covered Materials; or (ii) any use of the Covered Materials by Partner that violates Applicable Law or the terms of this Agreement. In order to resolve any Third-Party Claim relating to subsection 17.1(a), Supabase may, but is not obligated to: (a) modify or replace the Covered Materials to make them non-infringing; (b) procure any rights from a third party necessary to provide the Covered Materials; or (c) replace the Covered Materials with work product that is materially equal but is non-infringing. If none of the foregoing remedies is available to Supabase on commercially reasonable terms, Supabase may terminate the Agreement. EXCEPT AS MAY OTHERWISE BE PROVIDED IN APPLICABLE PROGRAM ADDENDUM(S), THIS SECTION 17.1(a) and (b) STATES PARTNER'S SOLE AND EXCLUSIVE REMEDY, AND SUPABASE'S SOLE AND EXCLUSIVE LIABILITY, REGARDING INFRINGEMENT OR MISAPPROPRIATION OF ANY INTELLECTUAL PROPERTY RIGHTS OF A THIRD PARTY. + +### 17.2 Partner Indemnification. + +Partner will defend, indemnify, and hold harmless Supabase and its directors, officers, employees, representatives, and agents (collectively, the “**Supabase Indemnitees**”) from and against any and all Losses to the extent based upon or arising from Third-Party Claims alleging: (i) Partner's gross negligence or willful misconduct, or fraudulent misrepresentation; (ii) Partner's breach of Section 3.2; (iii) Partner's use of the Prospect Information in breach of this Agreement; and/or (iv) Partner's violation of any Applicable Law. + +### 17.3 Indemnification Procedure. + +A Partner Indemnitee or Supabase Indemnitee (each, an “**Indemnitee**”) shall promptly provide the other Party providing the indemnification (each, an “**Indemnifying Party**”) with: (i) prompt written notice of the Third-Party Claim (provided that the failure to provide such notice will not relieve a Party of its obligations unless such failure prejudices its ability to defend the Third-Party Claim); (ii) sole control of the defense and settlement of the Third-Party Claim (except that the Indemnitee's prior written approval will be required for any settlement that requires any action, inaction, or admission by the Indemnitee, requires the payment of any amount that will not be fully satisfied by the Indemnifying Party or does not include a complete release of claims against the Indemnitee, such approval not to be unreasonably withheld, conditioned, or delayed); and (iii) cooperation as reasonably requested by the Indemnifying Party at the Indemnifying Party's expense in connection with the defense of the Third-Party Claim. The Indemnitee may participate in any indemnified matter with counsel of its' choosing at its' own expense. + +## 18\. Limitations of Liability. + +TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, AND EXCEPT AS OTHERWISE EXPRESSLY PROVIDED IN THIS SECTION 18 OR IN AN APPLICABLE PROGRAM ADDENDUM: (a) IN NO EVENT SHALL EITHER PARTY, ITS AFFILIATES OR THEIR EMPLOYEES, AGENTS, CONTRACTORS, OFFICERS OR DIRECTORS BE LIABLE FOR ANY INDIRECT, PUNITIVE, INCIDENTAL, SPECIAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES, INCLUDING WITHOUT LIMITATION DAMAGES FOR BUSINESS INTERRUPTION, LOSS OF PROFITS, GOODWILL, USE, DATA OR OTHER INTANGIBLE LOSSES ARISING IN CONNECTION WITH THE AGREEMENT OR ANY PROGRAM, INCLUDING (IN SUPABASE'S CASE) WITHOUT LIMITATION ANY INVESTMENTS, EXPENDITURES OR COMMITMENTS BY PARTNER IN CONNECTION WITH A PROGRAM; AND (b) IN NO EVENT SHALL SUPABASE'S CUMULATIVE AND AGGREGATE LIABILITY UNDER THE AGREEMENT EXCEED US$500 (THE “**LIABILITY CAP**”). THE EXCLUSIONS AND LIMITATIONS IN THIS SECTION APPLY WHETHER THE ALLEGED LIABILITY IS BASED ON CONTRACT, TORT, NEGLIGENCE, STRICT LIABILITY OR ANY OTHER BASIS, EVEN IF A PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NOTWITHSTANDING THE FOREGOING, THE LIABILITY CAP SHALL NOT APPLY TO LIABILITIES ARISING FROM OR RELATING TO EITHER PARTY'S GROSS NEGLIGENCE, WILLFUL MISCONDUCT, OR FRAUDULENT MISREPRESENTATION. + +## 19\. Notices. + +All notices under this Agreement shall be in writing and sent to the email address on the signature page of the Program Authorization (or as updated in writing). Notices are effective upon email transmission (provided no delivery failure notification is received). + +## 20\. Assignment. + +This Agreement binds and benefits each Party and its permitted successors and assigns. Supabase may assign this Agreement without consent in connection with a merger, acquisition, sale of all or substantially all of its assets, or change of control, or to an Affiliate, provided the assignee agrees to be bound by the terms of this Agreement. Any other assignment requires the non-assigning Party’s prior written consent (not to be unreasonably withheld). Any unauthorized assignment is void. + +## 21\. Third-Party Beneficiaries. + +Except as may otherwise expressly provided in a Program Addendum, the Agreement is for the sole benefit of the Parties and their respective successors and permitted assigns and nothing herein, express or implied, is intended to or shall confer on any other person any legal or equitable right, benefit or remedy of any nature whatsoever under or by reason of the Agreement. + +## 22\. Force Majeure. + +Neither Party shall be liable or responsible to the other Party, nor be deemed to have defaulted under or breached the Agreement, for any failure or delay in fulfilling or performing any term of the Agreement (except for any obligations to make payments and each Party's confidentiality obligations), when and to the extent such failure or delay arises from a cause or causes beyond its reasonable control (each of the foregoing, a “**Force Majeure Event**”), in each case, provided the event is outside the reasonable control of the affected Party, the affected Party provides prompt notice to the other Party stating the period of time the occurrence is expected to continue, and the affected Party uses diligent efforts to end the failure or delay and minimize the effects of such Force Majeure Event. + +## 23\. Governing Law; Venue. + +This Agreement shall be governed by the laws of the State of California, without regard to its conflict of law principles. The Parties shall first attempt in good faith to resolve any dispute, claim, or controversy arising out of or relating to this Agreement (a "**Dispute**") through informal negotiation between executives with authority to settle. If the Dispute is not resolved within thirty (30) days after written notice, the Dispute shall be finally resolved by binding arbitration administered by the American Arbitration Association ("**AAA**") under its Commercial Arbitration Rules, including the Expedited Procedures, before a single arbitrator; provided that either Party may elect to have the standard (non-expedited) Commercial Arbitration Rules apply to any Dispute in which the aggregate amount in controversy exceeds US$1,000,000. The seat and legal place of the arbitration shall be Santa Clara, California. The arbitrator's award shall be final and binding, and judgment on the award may be entered in any court of competent jurisdiction. Each Party shall bear its own attorneys' fees and costs, and the Parties shall share equally the AAA administrative fees and the arbitrator's compensation, subject to the arbitrator's authority to reallocate such fees and costs in the award. The arbitration and all related submissions and awards shall be treated as Confidential Information under Section 11, except as required to enforce or challenge the award or comply with Applicable Law. Notwithstanding the foregoing, either Party may seek temporary or preliminary injunctive or other equitable relief in any court of competent jurisdiction to protect its Intellectual Property Rights or Confidential Information, and the Parties consent to the exclusive jurisdiction of the state and federal courts located in San Francisco County, California for such purposes. EACH PARTY WAIVES ANY RIGHT TO A TRIAL BY JURY AND TO PARTICIPATE IN ANY CLASS, COLLECTIVE, OR REPRESENTATIVE ACTION. + +## 24\. Miscellaneous. + +To the extent that there is any conflict among the MPPA, the Program Addendum(s), and the Program Guide, such conflict will be governed in the following order: (i) the terms of the applicable Program Addendum(s); then (ii) the terms of this MPPA; then (iii) the Program Guide. Except as otherwise provided in Section 26, the Agreement, including this MPPA, may be modified only by a written instrument duly executed by authorized representatives of the Parties. The Agreement is the result of negotiations between sophisticated commercial entities; accordingly, the Parties waive any rule of construction dictating that ambiguities in the Agreement be construed against the drafter. Additionally, the Agreement supersedes any confidentiality or non-disclosure agreement, previously entered into by the Parties. The failure of a Party to exercise or enforce any condition, term or provision of the Agreement will not operate as a waiver of such condition, term or provision. Any waiver by either Party of any condition, term or provision of the Agreement shall not be construed as a waiver of any other condition, term or provision. No waiver of any breach of the Agreement, will be effective unless in writing and signed by an authorized representative of the Party against whom enforcement is sought. No waiver of any breach of the Agreement and no course of dealing between the Parties will be construed as a waiver of any subsequent breach of the Agreement. If any provision of the Agreement is held invalid or unenforceable, the remainder of the Agreement shall continue in full force and effect. The headings in this MPPA, and all Program Addendums, are for reference only and shall not affect the interpretation of the Agreement. For purposes of the Agreement, the words "include," "includes" and "including" are deemed to be followed by the words "without limitation"; the word "or" is not exclusive; and the words "herein," "hereby," "hereto" and "hereunder" refer to the Agreement as a whole. The Agreement may be executed in counterparts, each of which will be deemed an original, but which together will constitute one and the same instrument. Electronic execution and delivery of the Agreement is legal, valid, and binding execution and delivery for all purposes. + +## 25\. Definitions. + +Capitalized terms not otherwise defined in the Agreement shall have the respective meanings assigned to them in this Section 25\. + +“**Affiliate**” means, with respect to a Party, a business entity that directly or indirectly controls, is controlled by or is under common control with, such Party, where "**control**" means the direct or indirect ownership of more than 50% of the voting securities of a business entity. + +“**Applicable Law**” means any and all governmental laws, rules, directives, regulations or orders that are applicable to a particular Party's performance under the Agreement. + +“**Applicable Data Protection Laws**” means all Applicable Laws relating to the processing of Personal Data, privacy, and data security. + +“**AUP**” means Supabase's standard Acceptable Use Policy, currently available at [https://supabase.com/aup](https://supabase.com/aup). + +“**Branding Guidelines**” means Supabase's standard branding guidelines, as may be provided by Supabase to Partner. + +“**Close Family Member**” means a spouse, an individual's and a spouse's grandparents, parents, siblings, children, nieces, nephews, aunts, uncles, first cousins, the spouse of any of these people, or any other individuals who share the same household. + +“**Content**” means: (a) Program Content where Supabase is the Grantor and (b) Partner Content where Partner is the Grantor. + +“**End-Customer**” means a Supabase customer that has subscribed to the Services. + +“**Feedback**” means bug reports, suggestions or other feedback with respect to Program Content, or the Services provided by Partner to Supabase, exclusive of any Partner Confidential Information therein. + +“**Government Entity**” means (a) any national, state, regional, or local government (including, in each case, any agency, department, or subdivision of such government); (b) any political party; (c) any entity or business that is owned or controlled by any of those bodies listed in subcategory (a) or (c); or (d) any international organization, such as the United Nations or the World Bank. + +“**Government Official**” means (a) any director, officer, employee, agent, or representative (including anyone elected, nominated, or appointed to be a director, officer, employee, agent, or representative) of any Government Entity, or anyone otherwise acting in an official capacity on behalf of a Government Entity; (b) any political party, political party official, or political party employee; (c) any candidate for public or political office; (d) any royal or ruling family member; or (e) any agent or representative of any of those persons listed in subcategories (a) through (d). + +“**Intellectual Property Rights**” means any and all registered and unregistered rights granted, applied for, or otherwise now or hereafter in existence under or related to any patent, copyright, trademark, trade secret, database protection, or other intellectual property rights laws, and all similar or equivalent rights or forms of protection, in any part of the world. + +“**Marks**” means, with respect a Party as Grantor, its name and such service marks as it may make available to Grantee for limited use in accordance with Section 6\. + +“**Partner Content**” means such content (excluding software and hosted services) that Partner, at its option, makes available to Supabase for use by Supabase in accordance with Section 6 in connection with its participation in the applicable Program. + +“**Partner Portal**” means any online portal for one or more Programs that Supabase may make available to Partner. + +“**Partner Site**” means Supabase's standard information site for the Supabase Partner Program, currently available at [https://supabase.com/partners](https://supabase.com/partners). + +“**Personal Data**” means information relating to an identified or identifiable natural person that is protected by Applicable Laws, including Applicable Data Protection Laws, with respect to privacy where the individual resides. + +“**Privacy Policy**” means Supabase's standard Privacy Policy, currently available at [https://supabase.com/privacy](https://supabase.com/privacy) as updated from time to time. + +“**Process**” means to perform an operation or set of operations on data, content or information, including to submit, transmit, post, transfer, disclose, collect, record, organize, structure, store, adapt or alter; “**Processing**” has a correlative meaning. + +“**Program**” means the Partner programs Supabase offers Partners to participate in accordance with this MPPA or in applicable Program Addendum(s), as may be further described at the Partner Site. + +“**Program Addendum**” means the applicable addenda to this MPPA as provided at [https://supabase.com/ /legal/partner-resources/program-addenda](file:///legal/partner-resources/program-addenda) or, such other addendum to this MPPA as otherwise agreed to in writing by Supabase and Partner, which contains terms and conditions that govern Partner's participation in a Program. + +“**Program Authorization**” means the grant by Supabase to Partner of authority to participate in the specified Program(s) as signed by the Parties in writing and which is governed by the Agreement, unless otherwise agreed by the Parties in writing. + +“**Program Content**” means such Program-related content (excluding software and Services) that Supabase may make available to Partner through the Partner Portal or otherwise for use by Partner in accordance with Section 6 in furtherance of Partner's participation in the applicable Program(s). + +“**Program Guide**” means any program guide made available to Partner by Supabase, as may be updated from time to time. + +“**Service Terms**” means the terms and conditions available at [https://supabase.com/terms](https://supabase.com/terms), unless otherwise agreed in writing by the Parties. + +“**Services**” means the services that are made available by Supabase. + +“**Site Policies**” means the AUP, and Privacy Policy. + +“**User Guide**” means Supabase's standard user documentation for the Services, currently available at [https://supabase.com/docs](https://supabase.com/docs). + +## 26\. Changes to Program and Agreement. + +Except as otherwise expressly provided in applicable Program Addendum(s), Supabase reserves the right to modify or discontinue any Program, including any associated Program Guide, Program Content, the Partner Site and the Partner Portal, at any time in its sole discretion. Supabase may change this Agreement from time to time at its discretion. The date on which the Agreement was last modified will be updated at the top of this Agreement. Amendments to this Agreement will only take effect on Partner, on the renewal of this Agreement only when the Parties enter into a subsequent Program Authorization. diff --git a/apps/www/pages/legal/index.tsx b/apps/www/pages/legal/index.tsx new file mode 100644 index 00000000000..2d5d062fa14 --- /dev/null +++ b/apps/www/pages/legal/index.tsx @@ -0,0 +1,67 @@ +import DefaultLayout from '~/components/Layouts/Default' +import SectionContainer from '~/components/Layouts/SectionContainer' +import PageHeader from '~/components/Sections/PageHeader' +import { FileText, List } from 'lucide-react' +import { NextSeo } from 'next-seo' +import Link from 'next/link' + +const sections = [ + { + id: 'partner-legal-resources', + title: 'Partner Legal Resources', + links: [ + { + label: 'Master Partner Program Agreement', + href: '/legal/partner-resources/master-partner-program-agreement', + type: 'document' as const, + }, + { + label: 'Program Addenda', + href: '/legal/partner-resources/program-addenda', + type: 'index' as const, + }, + ], + }, +] + +const linkIcons = { + document: FileText, + index: List, +} + +export default function LegalHubPage() { + return ( + + + + +
      + {sections.map((section) => ( +
      +

      {section.title}

      +
      + {section.links.map((link) => { + const Icon = linkIcons[link.type] + return ( +
      + + + {link.label} + +
      + ) + })} +
      +
      + ))} +
      +
      +
      + ) +} diff --git a/apps/www/pages/legal/partner-resources/master-partner-program-agreement.tsx b/apps/www/pages/legal/partner-resources/master-partner-program-agreement.tsx new file mode 100644 index 00000000000..9d9c86bde45 --- /dev/null +++ b/apps/www/pages/legal/partner-resources/master-partner-program-agreement.tsx @@ -0,0 +1,43 @@ +import { MDXProvider } from '@mdx-js/react' +import DefaultLayout from '~/components/Layouts/Default' +import SectionContainer from '~/components/Layouts/SectionContainer' +import LegalDocVersions, { type LegalDocVersion } from '~/components/Legal/LegalDocVersions' +import PageBreadcrumb from '~/components/Sections/PageBreadcrumb' +import PageHeader from '~/components/Sections/PageHeader' +import V1 from '~/data/legal/partner-resources/mppa/v1.mdx' +import mdxComponents from '~/lib/mdx/mdxComponents' +import { NextSeo } from 'next-seo' + +const meta = { + title: 'Master Partner Program Agreement', + description: 'Supabase Master Partner Program Agreement', +} + +const versions: LegalDocVersion[] = [ + { id: 'v1', label: 'Version 1', effectiveDate: 'May 27, 2026', Component: V1 }, +] + +export default function MasterPartnerProgramAgreementPage() { + return ( + + + + } + h1="Master Partner Program Agreement" + subheader="The governing agreement for participants in the Supabase partner program." + /> + + + + + + + ) +} diff --git a/apps/www/pages/legal/partner-resources/program-addenda/index.tsx b/apps/www/pages/legal/partner-resources/program-addenda/index.tsx new file mode 100644 index 00000000000..c4c9ead6d0c --- /dev/null +++ b/apps/www/pages/legal/partner-resources/program-addenda/index.tsx @@ -0,0 +1,66 @@ +import DefaultLayout from '~/components/Layouts/Default' +import SectionContainer from '~/components/Layouts/SectionContainer' +import PageBreadcrumb from '~/components/Sections/PageBreadcrumb' +import PageHeader from '~/components/Sections/PageHeader' +import { FileText } from 'lucide-react' +import { NextSeo } from 'next-seo' +import Link from 'next/link' +import { Badge } from 'ui' + +const addenda = [ + { + label: 'Integration Partner Addendum', + href: '/legal/partner-resources/program-addenda/integration-partner-addendum', + effectiveDate: 'May 27, 2026', + }, +] + +export default function ProgramAddendaPage() { + return ( + + + + } + h1="Program Addenda" + subheader={ + <> + Addenda to the{' '} + + Master Partner Program Agreement + + . Each addendum modifies and supplements the master agreement for a specific partner + type. Partners are bound by the addendum corresponding to their participation tier. + + } + /> + +

      Current addenda

      +

      Additional partner-type addenda will be added as the program expands.

      +
      + {addenda.map((item) => ( +
      + + + {item.label} + + Effective {item.effectiveDate} +
      + ))} +
      +
      +
      + ) +} diff --git a/apps/www/pages/legal/partner-resources/program-addenda/integration-partner-addendum.tsx b/apps/www/pages/legal/partner-resources/program-addenda/integration-partner-addendum.tsx new file mode 100644 index 00000000000..deb570cd220 --- /dev/null +++ b/apps/www/pages/legal/partner-resources/program-addenda/integration-partner-addendum.tsx @@ -0,0 +1,44 @@ +import { MDXProvider } from '@mdx-js/react' +import DefaultLayout from '~/components/Layouts/Default' +import SectionContainer from '~/components/Layouts/SectionContainer' +import LegalDocVersions, { type LegalDocVersion } from '~/components/Legal/LegalDocVersions' +import PageBreadcrumb from '~/components/Sections/PageBreadcrumb' +import PageHeader from '~/components/Sections/PageHeader' +import V1 from '~/data/legal/partner-resources/integration-partner-addendum/v1.mdx' +import mdxComponents from '~/lib/mdx/mdxComponents' +import { NextSeo } from 'next-seo' + +const meta = { + title: 'Integration Partner Addendum', + description: 'Supabase Integration Partner Addendum', +} + +const versions: LegalDocVersion[] = [ + { id: 'v1', label: 'Version 1', effectiveDate: 'May 27, 2026', Component: V1 }, +] + +export default function IntegrationPartnerAddendumPage() { + return ( + + + + } + h1="Integration Partner Addendum" + subheader="An addendum to the Master Partner Program Agreement governing integration partners." + /> + + + + + + + ) +} From 5ea3785b84145cfec037c77911c613634a181a39 Mon Sep 17 00:00:00 2001 From: Ignacio Dobronich Date: Wed, 10 Jun 2026 18:00:30 -0300 Subject: [PATCH 075/134] fix: clarify business purchase tooltip copy (#46792) Reword the "I'm purchasing as a business" tooltip to frame it around needing a tax ID rather than being "tax-registered." ## Summary by CodeRabbit * **Documentation** * Updated payment method setup guidance to clarify when to enable tax ID information and confirm receipts remain available regardless of this setting. --- .../Payment/PaymentMethods/NewPaymentMethodElement.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/studio/components/interfaces/Billing/Payment/PaymentMethods/NewPaymentMethodElement.tsx b/apps/studio/components/interfaces/Billing/Payment/PaymentMethods/NewPaymentMethodElement.tsx index 183684a6d5a..5990e93691b 100644 --- a/apps/studio/components/interfaces/Billing/Payment/PaymentMethods/NewPaymentMethodElement.tsx +++ b/apps/studio/components/interfaces/Billing/Payment/PaymentMethods/NewPaymentMethodElement.tsx @@ -356,9 +356,10 @@ export const NewPaymentMethodElement = forwardRef( /> - Select this only if your business is tax-registered. You’ll be asked for a tax ID - (e.g. US EIN, VAT, GST), which is required to issue a compliant business invoice. If - you’re not tax-registered, leave this unchecked. You’ll still receive a receipt. + Check this only if you need a tax ID (e.g. US EIN, VAT, GST) on your invoice. You’ll + be asked to enter it, and it’ll appear on a compliant business invoice. If you don’t + have a tax ID, or don’t need one shown, leave this unchecked. You’ll still receive a + receipt.
      From 135ab6dfcbc0f04bafd3103c283c3a2163489363 Mon Sep 17 00:00:00 2001 From: Leandro Pereira Date: Wed, 10 Jun 2026 17:07:29 -0400 Subject: [PATCH 076/134] fix: make Realtime card clickable (#46809) To reproduce: - resize viewport to mobile - try to click the Realtime card Tested on Brave. ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Bug fix. ## What is the current behavior? Click doesn't work on mobile. ## Summary by CodeRabbit * **Bug Fixes** * Product cards are now interactive and respond to user clicks and hover interactions. --- apps/www/components/Products/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/www/components/Products/index.tsx b/apps/www/components/Products/index.tsx index 4ee88b3f6ab..1ca3db3d81c 100644 --- a/apps/www/components/Products/index.tsx +++ b/apps/www/components/Products/index.tsx @@ -118,7 +118,7 @@ const Products: React.FC = (props) => { onClick={() => sendTelemetryEvent(PRODUCT_SHORTNAMES.REALTIME)} image={} className=" - col-span-6 pointer-events-none xl:col-span-3 + col-span-6 xl:col-span-3 hover:cursor-[url('/images/index/products/realtime-cursor-light.svg'),auto]! dark:hover:cursor-[url('/images/index/products/realtime-cursor-dark.svg'),auto]! " From cb6ad35ac1d667c949095ad67bb344d505e34abd Mon Sep 17 00:00:00 2001 From: Miranda Limonczenko <23711156+czenko@users.noreply.github.com> Date: Wed, 10 Jun 2026 23:59:08 -0700 Subject: [PATCH 077/134] feat(docs) Add external link indicator for screenreader and visual (#46825) --- apps/docs/features/docs/MdxAnchor.tsx | 46 ++++++++++++++++++++++ apps/docs/features/docs/MdxBase.shared.tsx | 2 + 2 files changed, 48 insertions(+) create mode 100644 apps/docs/features/docs/MdxAnchor.tsx diff --git a/apps/docs/features/docs/MdxAnchor.tsx b/apps/docs/features/docs/MdxAnchor.tsx new file mode 100644 index 00000000000..30b2b54db42 --- /dev/null +++ b/apps/docs/features/docs/MdxAnchor.tsx @@ -0,0 +1,46 @@ +import { ExternalLink as ExternalLinkIcon } from 'lucide-react' +import { type ComponentPropsWithoutRef } from 'react' +import { cn } from 'ui' + +const isExternalHref = (href?: string) => { + if (!href || !/^https?:\/\//i.test(href)) return false + try { + return !/(^|\.)supabase\.com$/i.test(new URL(href).hostname) + } catch { + return false + } +} + +// Walk the tree and concatenate text so the aria-label matches the visible link +const flattenChildrenToText = (node: unknown): string => { + if (node == null || typeof node === 'boolean') return '' + if (typeof node === 'string' || typeof node === 'number') return String(node) + if (Array.isArray(node)) return node.map(flattenChildrenToText).join('') + if (typeof node === 'object' && node !== null && 'props' in node) { + const props = (node as { props?: { children?: unknown } }).props + return flattenChildrenToText(props?.children) + } + return '' +} + +export function MdxAnchor({ href, children, ...rest }: ComponentPropsWithoutRef<'a'>) { + if (!isExternalHref(href)) { + return ( + + {children} + + ) + } + const label = flattenChildrenToText(children).trim() + return ( + + {children} + + ) +} diff --git a/apps/docs/features/docs/MdxBase.shared.tsx b/apps/docs/features/docs/MdxBase.shared.tsx index 134ffc1ed31..591a8bf20cb 100644 --- a/apps/docs/features/docs/MdxBase.shared.tsx +++ b/apps/docs/features/docs/MdxBase.shared.tsx @@ -19,6 +19,7 @@ import { SharedData } from '~/components/SharedData' import StepHikeCompact from '~/components/StepHikeCompact' import { CodeSampleDummy, CodeSampleWrapper } from '~/features/directives/CodeSample.client' import { NamedCodeBlock } from '~/features/directives/CodeTabs.components' +import { MdxAnchor } from '~/features/docs/MdxAnchor' import { Accordion, AccordionItem } from '~/features/ui/Accordion' import { CodeBlock } from '~/features/ui/CodeBlock/CodeBlock' import InfoTooltip from '~/features/ui/InfoTooltip' @@ -100,6 +101,7 @@ const components = { Tabs, TabPanel, InfoTooltip, + a: MdxAnchor, h2: (props: any) => ( {props.children} From cb644962b6c2c5c42a123b2f68e97ead9ced49f0 Mon Sep 17 00:00:00 2001 From: Taryn King <49492414+tk1ng@users.noreply.github.com> Date: Thu, 11 Jun 2026 01:59:44 -0500 Subject: [PATCH 078/134] =?UTF-8?q?chore(docs):=20add=20details=20and=20tr?= =?UTF-8?q?oubleshooting=20steps=20for=20auth=20schema=20er=E2=80=A6=20(#4?= =?UTF-8?q?6789)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../database-error-saving-new-user-RU_EwB.mdx | 78 +++++++++++++++++-- 1 file changed, 72 insertions(+), 6 deletions(-) diff --git a/apps/docs/content/troubleshooting/database-error-saving-new-user-RU_EwB.mdx b/apps/docs/content/troubleshooting/database-error-saving-new-user-RU_EwB.mdx index d054f6f4020..64a2d0b389c 100644 --- a/apps/docs/content/troubleshooting/database-error-saving-new-user-RU_EwB.mdx +++ b/apps/docs/content/troubleshooting/database-error-saving-new-user-RU_EwB.mdx @@ -7,22 +7,88 @@ keywords = [ "users" ] database_id = "5d1c44ed-b2f6-4509-9312-1eeb8838e701" [[errors]] +http_status_code = 500 +code = "unexpected_failure" message = "Database error saving new user" + +[[errors]] +http_status_code = 500 +code = "unexpected_failure" +message = "Database error creating new user" --- -You generally get this error when trying to invite a new user from the dashboard or when trying to insert a user into a table using the table editor in the Supabase dashboard. +You generally get this error when trying to invite a new user from the dashboard or when trying to insert a user into a table using the table editor in the Supabase dashboard. You may also see this error in logs in connection to failed signups. This error is normally associated with a side effect of a database transaction. **Common causes of this error:** -- You have a trigger/trigger function setup on the `auth.users` table +- You have a trigger/trigger function setup on the `auth.users` table that has an error - You have added a constraint on the `auth.users` table which isn't being met - You are using Prisma and it has broken all the permissions on the `auth.users` table -**Debugging this error:** +## Debugging this error: -- You can use the [Auth logs explorer](https://app.supabase.com/project/_/logs/auth-logs) to find the issue with more information -- You can use the [Postgres logs explorer](https://app.supabase.com/project/_/logs/postgres-logs) +**Step 1: Check the Auth logs** -https://user-images.githubusercontent.com/79497/225517698-b6e3ccaf-cd70-4acd-8124-ffbcee310d63.mp4 +Start in the [Auth logs explorer](/dashboard/project/_/logs/auth-logs) in your project dashboard. The logs surface the specific error message and give you the most direct signal about what went wrong. + +**Step 2: Check the Postgres logs** + +If the Auth logs point to a database-level issue, open the [Postgres logs explorer](/dashboard/project/_/logs/postgres-logs) to look for corresponding errors. + +--- + +## Common errors + +### NULL value in auth schema column + +**Example Auth log error:** + +``` +500: Database error querying schema +error finding user: sql: Scan error on column index 8, name "confirmation_token": converting NULL to string is unsupported +``` + +**Cause:** + +The `auth` schema is managed by Supabase and expects specific column formats. This error typically happens when users are inserted directly via SQL or using an AI tool that uses a direct SQL `INSERT`, rather than through the [Auth API](/docs/reference/javascript/auth-api). A direct insert can leave required columns as `NULL` when the Auth service expects an empty string. + +**Fix:** + +Run the following in the [SQL editor](/dashboard/project/_/sql), replacing `confirmation_token` with whichever column appears in your error message: + +```sql +update auth.users +set confirmation_token = '' +where confirmation_token is null; +``` + +This sets all `NULL` values in that column to an empty string, which is what the Auth service expects. + +--- + +### Relation does not exist + +**Example Auth log error:** + +``` +failed to close prepared statement: ERROR: current transaction is aborted, commands ignored until end of transaction block (SQLSTATE 25P02): ERROR: relation "profiles" does not exist (SQLSTATE 42P01) +``` + +**Example Postgres log error:** + +``` +event_message: "relation "profiles" does not exist" +context: "PL/pgSQL function public.handle_new_user() line 3 at SQL statement" +``` + +**Cause:** + +A trigger on `auth.users` is calling a function (in this case `handle_new_user`) that tries to insert into a table that does not exist. This is common when a `profiles` table is referenced in a trigger function but was never created, or was accidentally dropped. + +**Fix:** + +1. Check whether the missing table should exist in your `public` schema. If it should, create the table for the trigger to succeed and the error should resolve. + +2. If the table is not needed, review the function definition and update or remove the reference. You can view and edit your database functions from the [Database Functions](/dashboard/project/_/database/functions) page in the dashboard. From 61754a0eec33d0e6f6a1ecac95f06cddac6b6321 Mon Sep 17 00:00:00 2001 From: Victor Farazdagi Date: Thu, 11 Jun 2026 10:25:57 +0300 Subject: [PATCH 079/134] feat(studio): add Snowflake replication destination (#46767) ## Details of change Adds Snowflake to the Studio replication destination flow: - destination selection and display - create/edit form fields - validate/create/update payload serialization - generated Platform API types Snowflake remains gated behind `etlEnableSnowflakePrivateAlpha`. **Note:** I have configured `etlEnableSnowflakePrivateAlpha` in ConfigCat ("all" in staging and tied to my own org id in prod). ## Details of Verification Process - Studio focused Vitest coverage for form serialization and diagram mapping - Studio typecheck - ESLint on changed Studio replication files - Local `mise fullstack:dev` smoke test to confirm the Snowflake form renders ok. image Full create/validate E2E depends on the Platform PR and ETL runtime rollout. ## Review Requests Please check the Snowflake wire payload matches the Platform/ETL contract and that gating/edit/display behavior follows the existing ETL destination patterns. ## Summary by CodeRabbit * **New Features** * Snowflake added as a supported replication destination (private-alpha gated), including UI for selecting and configuring connection and auth (account, user, database, schema, role, private key, optional passphrase). * **Validation** * Form validation and submission now handle Snowflake-specific required/optional fields. * **Tests** * Unit tests added for Snowflake form behavior and replication-type detection. * **API** * Destination create/update/validate flows extended to accept Snowflake payloads. --- .../DestinationForm/DestinationForm.schema.ts | 8 + .../DestinationForm.utils.test.ts | 110 +++++++++ .../DestinationForm/DestinationForm.utils.ts | 75 ++++++ .../DestinationPanelFields.tsx | 162 ++++++++++++ .../DestinationForm/index.tsx | 45 +++- .../DestinationPanel/DestinationPanel.tsx | 1 + .../DestinationPanel.types.ts | 7 +- .../DestinationTypeSelection.tsx | 34 ++- .../Database/Replication/DestinationRow.tsx | 4 +- .../Database/Replication/Destinations.tsx | 7 +- .../Replication/ReplicationDiagram/Nodes.tsx | 2 + .../ReplicationDiagram/Nodes.utils.test.ts | 4 + .../ReplicationDiagram/Nodes.utils.ts | 3 +- .../Replication/useIsETLPrivateAlpha.ts | 12 +- .../create-destination-pipeline-mutation.ts | 32 ++- .../update-destination-pipeline-mutation.ts | 18 +- .../validate-destination-mutation.ts | 19 +- packages/api-types/types/platform.d.ts | 231 ++++++++++++++++++ 18 files changed, 759 insertions(+), 15 deletions(-) diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationForm.schema.ts b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationForm.schema.ts index f2a663138fa..dd0da8a8e47 100644 --- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationForm.schema.ts +++ b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationForm.schema.ts @@ -43,6 +43,14 @@ export const DestinationPanelFormSchema = z.object({ ducklakeS3UrlStyle: z.enum(['path', 'vhost']).optional(), ducklakeS3UseSsl: z.boolean().optional(), ducklakeMetadataSchema: z.string().optional(), + // Snowflake fields + snowflakeAccountId: z.string().optional(), + snowflakeUser: z.string().optional(), + snowflakePrivateKey: z.string().optional(), + snowflakePrivateKeyPassphrase: z.string().optional(), + snowflakeDatabase: z.string().optional(), + snowflakeSchema: z.string().optional(), + snowflakeRole: z.string().optional(), }) export type DestinationPanelSchemaType = z.infer diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationForm.utils.test.ts b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationForm.utils.test.ts index 571688989fa..bd07b6bd471 100644 --- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationForm.utils.test.ts +++ b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationForm.utils.test.ts @@ -4,6 +4,7 @@ import { buildDestinationConfig, buildDestinationConfigForValidation, getDucklakeValidationIssues, + getSnowflakeValidationIssues, } from './DestinationForm.utils' const baseDucklakeFormData = { @@ -37,6 +38,44 @@ const baseDucklakeFormData = { ducklakeMetadataSchema: ' ducklake_metadata ', } +const baseSnowflakeFormData = { + name: 'Snowflake Destination', + publicationName: 'pub', + maxFillMs: undefined, + maxTableSyncWorkers: undefined, + maxCopyConnectionsPerTable: undefined, + invalidatedSlotBehavior: undefined, + projectId: undefined, + datasetId: undefined, + serviceAccountKey: undefined, + connectionPoolSize: undefined, + maxStalenessMins: undefined, + warehouseName: undefined, + namespace: undefined, + newNamespaceName: undefined, + catalogToken: undefined, + s3AccessKeyId: undefined, + s3SecretAccessKey: undefined, + s3Region: undefined, + ducklakeCatalogUrl: undefined, + ducklakeDataPath: undefined, + ducklakePoolSize: undefined, + ducklakeS3AccessKeyId: undefined, + ducklakeS3SecretAccessKey: undefined, + ducklakeS3Region: undefined, + ducklakeS3Endpoint: undefined, + ducklakeS3UrlStyle: undefined, + ducklakeS3UseSsl: undefined, + ducklakeMetadataSchema: undefined, + snowflakeAccountId: ' MYORG-MYACCOUNT ', + snowflakeUser: ' ETL_USER ', + snowflakePrivateKey: '-----BEGIN PRIVATE KEY-----\nabc\n-----END PRIVATE KEY-----', + snowflakePrivateKeyPassphrase: ' secret passphrase ', + snowflakeDatabase: ' ANALYTICS ', + snowflakeSchema: ' PUBLIC ', + snowflakeRole: ' ETL_ROLE ', +} + describe('DestinationForm.utils DuckLake', () => { it('builds DuckLake validation config with required fields trimmed and blank optionals removed', () => { const config = buildDestinationConfigForValidation({ @@ -160,3 +199,74 @@ describe('DestinationForm.utils DuckLake', () => { ).toEqual([]) }) }) + +describe('DestinationForm.utils Snowflake', () => { + it('builds Snowflake validation config with identifiers trimmed and secrets preserved', () => { + const config = buildDestinationConfigForValidation({ + projectRef: 'project-ref', + selectedType: 'Snowflake', + data: { + ...baseSnowflakeFormData, + snowflakePrivateKeyPassphrase: '', + snowflakeRole: ' ', + }, + }) + + expect(config).toEqual({ + snowflake: { + accountId: 'MYORG-MYACCOUNT', + user: 'ETL_USER', + privateKey: '-----BEGIN PRIVATE KEY-----\nabc\n-----END PRIVATE KEY-----', + privateKeyPassphrase: undefined, + database: 'ANALYTICS', + schema: 'PUBLIC', + role: undefined, + }, + }) + }) + + it('builds Snowflake submit config with normalized values', async () => { + const createS3AccessKey = vi.fn() + const resolveNamespace = vi.fn() + + const config = await buildDestinationConfig({ + projectRef: 'project-ref', + selectedType: 'Snowflake', + data: baseSnowflakeFormData, + createS3AccessKey, + resolveNamespace, + }) + + expect(config).toEqual({ + snowflake: { + accountId: 'MYORG-MYACCOUNT', + user: 'ETL_USER', + privateKey: '-----BEGIN PRIVATE KEY-----\nabc\n-----END PRIVATE KEY-----', + privateKeyPassphrase: ' secret passphrase ', + database: 'ANALYTICS', + schema: 'PUBLIC', + role: 'ETL_ROLE', + }, + }) + expect(createS3AccessKey).not.toHaveBeenCalled() + expect(resolveNamespace).not.toHaveBeenCalled() + }) + + it('returns required-field errors for missing Snowflake settings', () => { + const issues = getSnowflakeValidationIssues({ + snowflakeAccountId: '', + snowflakeUser: '', + snowflakePrivateKey: '', + snowflakeDatabase: '', + snowflakeSchema: '', + }) + + expect(issues).toEqual([ + { path: 'snowflakeAccountId', message: 'Account ID is required' }, + { path: 'snowflakeUser', message: 'User is required' }, + { path: 'snowflakePrivateKey', message: 'Private key is required' }, + { path: 'snowflakeDatabase', message: 'Database is required' }, + { path: 'snowflakeSchema', message: 'Schema is required' }, + ]) + }) +}) diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationForm.utils.ts b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationForm.utils.ts index 70b3bd5be8e..8f7d3a53e1b 100644 --- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationForm.utils.ts +++ b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationForm.utils.ts @@ -13,6 +13,7 @@ import { DestinationConfig, DucklakeDestinationConfig, IcebergDestinationConfig, + SnowflakeDestinationConfig, } from '@/data/replication/create-destination-pipeline-mutation' import { type CreateS3AccessKeyCredentialVariables, @@ -27,6 +28,10 @@ const normalizeOptionalString = (value?: string) => { const normalizeRequiredString = (value?: string) => value?.trim() ?? '' +const normalizeOptionalUntrimmedString = (value?: string) => { + return value && value.length > 0 ? value : undefined +} + type DucklakeFieldPath = | 'ducklakeCatalogUrl' | 'ducklakeDataPath' @@ -116,6 +121,53 @@ export const getDucklakeValidationIssues = ( return issues } +type SnowflakeFieldPath = + | 'snowflakeAccountId' + | 'snowflakeUser' + | 'snowflakePrivateKey' + | 'snowflakeDatabase' + | 'snowflakeSchema' + +export type SnowflakeValidationIssue = { + path: SnowflakeFieldPath + message: string +} + +export const getSnowflakeValidationIssues = ( + data: Pick< + DestinationPanelSchemaType, + | 'snowflakeAccountId' + | 'snowflakeUser' + | 'snowflakePrivateKey' + | 'snowflakeDatabase' + | 'snowflakeSchema' + > +): SnowflakeValidationIssue[] => { + const issues: SnowflakeValidationIssue[] = [] + + if (!data.snowflakeAccountId?.trim().length) { + issues.push({ path: 'snowflakeAccountId', message: 'Account ID is required' }) + } + + if (!data.snowflakeUser?.trim().length) { + issues.push({ path: 'snowflakeUser', message: 'User is required' }) + } + + if (!data.snowflakePrivateKey?.trim().length) { + issues.push({ path: 'snowflakePrivateKey', message: 'Private key is required' }) + } + + if (!data.snowflakeDatabase?.trim().length) { + issues.push({ path: 'snowflakeDatabase', message: 'Database is required' }) + } + + if (!data.snowflakeSchema?.trim().length) { + issues.push({ path: 'snowflakeSchema', message: 'Schema is required' }) + } + + return issues +} + // Helper function to build destination config for validation export const buildDestinationConfigForValidation = ({ projectRef, @@ -178,6 +230,18 @@ export const buildDestinationConfigForValidation = ({ metadataSchema: normalizeOptionalString(data.ducklakeMetadataSchema), }, } + } else if (selectedType === 'Snowflake') { + return { + snowflake: { + accountId: normalizeRequiredString(data.snowflakeAccountId), + user: normalizeRequiredString(data.snowflakeUser), + privateKey: data.snowflakePrivateKey ?? '', + privateKeyPassphrase: normalizeOptionalUntrimmedString(data.snowflakePrivateKeyPassphrase), + database: normalizeRequiredString(data.snowflakeDatabase), + schema: normalizeRequiredString(data.snowflakeSchema), + role: normalizeOptionalString(data.snowflakeRole), + }, + } } else { throw new Error('Invalid destination type') } @@ -256,6 +320,17 @@ export const buildDestinationConfig = async ({ metadataSchema: normalizeOptionalString(data.ducklakeMetadataSchema), } destinationConfig = { ducklake: ducklakeConfig } + } else if (selectedType === 'Snowflake') { + const snowflakeConfig: SnowflakeDestinationConfig = { + accountId: normalizeRequiredString(data.snowflakeAccountId), + user: normalizeRequiredString(data.snowflakeUser), + privateKey: data.snowflakePrivateKey ?? '', + privateKeyPassphrase: normalizeOptionalUntrimmedString(data.snowflakePrivateKeyPassphrase), + database: normalizeRequiredString(data.snowflakeDatabase), + schema: normalizeRequiredString(data.snowflakeSchema), + role: normalizeOptionalString(data.snowflakeRole), + } + destinationConfig = { snowflake: snowflakeConfig } } return destinationConfig diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationPanelFields.tsx b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationPanelFields.tsx index 55e5f478d8c..cf8b7b4bed4 100644 --- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationPanelFields.tsx +++ b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationForm/DestinationPanelFields.tsx @@ -345,6 +345,168 @@ export const DuckLakeFields = ({ form }: { form: UseFormReturn }) => { + const [showPrivateKeyPassphrase, setShowPrivateKeyPassphrase] = useState(false) + + return ( +
      +

      Snowflake settings

      + +
      +

      Connection

      +

      + Configure the Snowflake account, user, and target namespace for replicated data. +

      +
      + +
      + ( + + + + + + )} + /> + + ( + + + + + + )} + /> + + ( + + + + + + )} + /> + + ( + + + + + + )} + /> + + ( + + + + + + )} + /> +
      + +
      +

      Authentication

      +

      + Use the RSA private key whose public key is registered on the Snowflake user. +

      +
      + +
      + ( + + +